---
title: "Protest and incumbent support: Evidence from a natural experiment in Ghana"
subtitle: "Supplementary materials"
date: "This version: `r format(Sys.time(), '%d %B %Y')`"
output: 
 bookdown::pdf_document2:
toc: true
fontsize: 12pt
geometry: margin =0.75in
numbersections: true
citations_package: none
link-citations: yes
linkcolor: blue
header-includes:
- \usepackage[default]{sourcesanspro}
- \usepackage[T1]{fontenc}
- \usepackage{setspace}\onehalfspacing
- \usepackage{float}
- \usepackage{caption}
- \usepackage[labelfont=bf]{caption}
- \captionsetup[figure]{font=scriptsize}
- \usepackage[margin=1.5cm]{caption}
- \captionsetup[table]{font=scriptsize}
- \usepackage{lscape}
- \usepackage{booktabs}
- \usepackage{graphicx}
- \newcommand{\beginsupplement}{\setcounter{table}{0}  \renewcommand{\thetable}{A\arabic{table}} - \setcounter{figure}{0} \renewcommand{\thefigure}{A\arabic{figure}}}
- \pagenumbering{gobble}
bibliography: /protests_CPS.bib
---

```{r setup, include=FALSE}

knitr::opts_chunk$set(echo = FALSE, message=FALSE, warning=FALSE)

library(dplyr)
library(fixest)
library(sjPlot)
library(ggplot2)
library(reshape2)
library(lubridate)
library(broom)
library(purrr)
library(gridExtra)
library(ebal)
library(kableExtra)
library(haven)
library(ggstats)
library(tidyverse)

```

```{r load data}

rm(list=ls())
load("protests_CPS_data.RData")


```

\pagenumbering{arabic}

# Data description

## Sampling {#sampling}

Our experiment was embedded within a broader survey conducted in Ghana in September/October 2023. The wider survey studies various ways in which financial remittances, mobile phone access, and exposure to bribes shape public opinion in Ghana. The survey took place in three regions across the country: Greater Accra, Central, and Bono. For the purposes of this paper, due to survey timings as discussed in the main text, we focus on Greater Accra and Bono.

Our survey was implemented by the Ghana Centre for Democratic Development (CDD), a highly experienced research firm who also administer the Afrobarometer survey in Ghana. The CDD recruited enumerators, arranged logistics, and managed data collection. Enumerators attended a one-day training workshop in Accra, conducted by the research team.

We selected regions of Ghana which provided variation among our phenomena of interest, remittance receipt, while also exhibiting some level of political competition as to not overly bias our initial, pre-registered analyses which focused on perceptions of government corruption. Domestically, Bono region is known for being a heavily remittance-dependent part of the country while Greater Accra, as an urban centre, contains more remittance *senders*. Internationally, both Greater Accra and Central region have some of the highest rates of remittance receipt from abroad. To maintain political sampling Ghana's most remittance dependent Ashanti region, as it is a historic stronghold of the then-ruling NPP party. Figure \@ref(fig:remittances-by-region) below, taken from our pre-analysis plan, uses data from Afrobarometer round 7 to document these trends in remittance dependency (note that Bono region is contained within Brong Ahafo).^[We use round 7 figures to make the figure, as later rounds do not ask questions about remittance dependency.]

```{r remittances-by-region, fig.width = 8, fig.height=4, fig.cap="Mean remittance dependency by region in Ghana. Data taken from Round 7 of the Afrobarometer survey in Ghana, fielded in September 2017. Bars represent mean dependency among respondents across sampled and non-sampled regions. Note: Bono region was formed out of Brong Ahafo region following a 2018 referendum."}

### Regional breakdown in Ghana

data_remit <- r7sub %>%
  group_by(region) %>%
  mutate(remittances_bin = ifelse(remittances == 0, 0, 1), 
         remittances_wt = remittances*withinwt, 
         remittances_bin_wt = remittances_bin*withinwt) %>%
  summarise(mean_remit = mean(remittances_wt, na.rm=T), 
            mean_remit_bin = mean(remittances_bin_wt, na.rm=T)) %>%
  mutate(region_name = case_when(
      region == 260 ~ "Western",
      region == 261 ~ "Central",
      region == 262 ~ "Greater Accra",
      region == 263 ~ "Volta",
      region == 264 ~ "Eastern",
      region == 265 ~ "Ashanti",
      region == 266 ~ "Brong Ahafo",
      region == 267 ~ "Northern",
      region == 268 ~ "Upper East",
      region == 269 ~ "Upper West",
      TRUE ~ "Unknown"),
      Sampled = ifelse(region_name %in% c("Central", "Greater Accra", "Brong Ahafo"), 
                          "Sampled", "Not sampled"))

data_remit_full <- r7sub %>%
  mutate(region_name = case_when(
      region == 260 ~ "Western",
      region == 261 ~ "Central",
      region == 262 ~ "Greater Accra",
      region == 263 ~ "Volta",
      region == 264 ~ "Eastern",
      region == 265 ~ "Ashanti",
      region == 266 ~ "Brong Ahafo",
      region == 267 ~ "Northern",
      region == 268 ~ "Upper East",
      region == 269 ~ "Upper West",
      TRUE ~ "Unknown"),
      Sampled = ifelse(region_name %in% c("Central", "Greater Accra", "Brong Ahafo"), 
                          "Sampled", "Not sampled"))


## Plot it

ggplot(data_remit, aes(y=reorder(factor(region_name), mean_remit), 
                       x = mean_remit)) +
  geom_point(aes(col=factor(Sampled))) +
  scale_colour_manual(values = c("darkgrey", "darkred")) +
  geom_vline(xintercept = 
               mean(data_remit_full$remittances[data_remit_full$Sampled == "Sampled"]*
                      data_remit_full$withinwt, na.rm=T),
             col="darkred") +
  geom_vline(xintercept = 
               mean(data_remit_full$remittances[data_remit_full$Sampled == "Not sampled"]*
                      data_remit_full$withinwt, na.rm=T),
             col="darkgrey") +
  theme_minimal() +
  theme(axis.title.y = element_blank(), 
        legend.title = element_blank(), 
        legend.position = "bottom") +
  xlab("Mean remittance dependency") +
  labs(title = "Mean remittance dependency by region in Ghana", 
       subtitle = "Source: Afrobarometer Social Survey (Round 7)")

```

Within each region, we then selected respondents through a multistage sampling process in which communities are chosen at random, and individual respondents within communities are selected through quota and random-walk techniques. We used the following procedure: 

 1. With data from the most recent round of the Ghana census, we made a list all recorded “communities” in our three regions of interest according to the Ghanaian government. These communities are nested within districts, a second order administrative unit in Ghana (N=261).
 2. We took the subset of districts in each region which contained at least 10 communities. From within this subset, we randomly sampled 9 districts from the Greater Accra (GA) and Bono regions, and 5 from Central.
 3. From within these districts, we randomly selected 8 communities. In each district, the first 5 communities are *target* areas in which to conduct the survey. The remaining 3 are *back ups*, in the instance that some communities cannot be found, pose severe logistical constraints, or quotas cannot be met.
 4. Survey enumerators traveled to each community and conducted 10 interviews. Enumerators arriving at a community were instructed to select a starting point at a prominent, central location. In rural areas, they will begin walking in a straight line and invite every 5th individual they encounter to participate in an interview.^[Where respondents are in clusters, for instance a group of 10 friends sitting outside a shop, enumerators are instructed to conduct only one interview per cluster at maximum.] In urban areas, which are more densely populated and the precise counting of individuals might be more difficult, enumerators are instead instructed to walk 50 steps, stop, and invite the nearest person to an interview.

Given our survey's overarching focus on remittances, we sought to over-sample respondents who received some form of financial support from friends or relatives. We also sought to ensure rough gender balance, noting that this might be difficult in some more rural communities. 

To do this, we adopted a quota system in which enumerators asked a screening question to all respondents about past remittances. For each 10 interviews in a given community, the following quota was met: 2 male remittances, 1 female, remittances, 2 male, no remittances, 2 female, no remittances, 2 remittances [any gender], 1 no remittances [any gender]. Our final survey had 1,151 respondents: 450 from Bono, 451 from Greater Accra, and 250 from Central. 

In the main paper, we compare various demographic and political characteristics of individuals in our survey vs a recent round of the Afrobarometer. This is a useful benchmark, since the Afrobarometer is both larger than our survey, and is designed to be nationally representative. We briefly extend this analysis here, by comparing Afrobarometer respondents in our sampled regions with those living elsewhere in the country. Our sampled areas are slightly better educated and urban than the wider population, a trend discussed in detail in the main text. When turning to political variables, however, we see that respondents in sampled areas are no more likely to identify with, or intend to vote for, the ruling party. 

```{r afrobarometer external validity, results="asis"}

#### External validity of sample regions

setFixest_dict(c(age = "Age", 
                 gender_male = "Male",
                 education_num = "Education (0-3 scale)",
                 turnout = "Turnout", 
                 party_close = "Close to any party", 
                 party_id_govt_num = "Close to ruling party", 
                 intend_govt = "Intend to vote ruling party", 
                 sample_region = "Sampled region"))

ab_bal <- feols(c(age, gender_male, education_num, urban,
        turnout,
        party_close, party_id_govt_num, intend_govt) ~ sample_region, data=AB_r9)

etable(ab_bal[c(1:4)],
       title = "External validity of sampled regions (demographic)",
       drop = "Constant",
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       se.row=FALSE,
       tex=T)

etable(ab_bal[c(5:8)],
       drop = "Constant",
       title = "External validity of sampled regions (political)",
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       se.row=FALSE,
       tex=T)

```


## Ethics

Our survey received institutional ethical approval prior to implementation, All and respondents provided informed consent prior to participation. 

There are no reasons to believe our survey poses risk or harm to participants: responses are fully annonymised, were conducted by an experienced local partner organisation, and the small experimental interventions embedded within the survey (which we analyse in a separate study) provided factual information that was already salient and in the public domain.

\clearpage 

# Main results {#mainresultstabs}

The tables below present our main results, showing that respondents interviewed after the protest are more trusting and approving of the President.

```{r results-baseline-trust-and-approval-sm, fig.width=8, fig.height=4, fig.cap = "Main UESD specifications, presenting the impact of the Julorbi House protests on Presidential trust and approval. All models include region fixed effects, while covariate and entropy specifications account for age, gender, education, and urbancy. Bars represent 95% (thick) and 90% (thin) confidence intervals respectively. Number of observations are taken from baseline specifications on trust, and are marginally lower for specifications with additional controls. Collectively, the results suggest that respondents interviewed after the protest were more trusting and approving of the President."}

data <- data %>% mutate(bono = as.factor(bono))

#### 2 day bandwidth (N=336)

julorbi1.1 <- feols(c(trust_pres, performance_pres) ~ postJulorbi2days + bono, 
                    data=data) ## Baseline
julorbi1.2 <- feols(c(trust_pres, performance_pres) ~ postJulorbi2days + 
                      vote2020_inc + age + remittance_quota + 
                      gender + education + urbrur + urbrur_from + bono, data=data) ## Covariates
julorbi1.3 <- feols(c(trust_pres, performance_pres) ~ postJulorbi2days + bono, 
                    data=data_eb_2days, weights=~weights) # Entropy weights


#### 3 day bandwidth (N=508)

julorbi2.1 <- feols(c(trust_pres, performance_pres) ~ postJulorbi3days + bono, 
                    data=data)
julorbi2.2 <- feols(c(trust_pres, performance_pres) ~ postJulorbi3days + 
                      vote2020_inc + age + remittance_quota + 
                      gender + education + urbrur + urbrur_from + bono, data=data)
julorbi2.3 <- feols(c(trust_pres, performance_pres) ~ postJulorbi3days + bono, 
                    data=data_eb_3days, weights=~weights)

#### Full sample excl. protest days (N=627)

julorbi3.1 <- feols(c(trust_pres, performance_pres) ~ postJulorbi_donut + bono, 
                    data=data) 
julorbi3.2 <- feols(c(trust_pres, performance_pres) ~ postJulorbi_donut + 
                      vote2020_inc + age + remittance_quota + 
                      gender + education + urbrur + urbrur_from + bono, data=data) 
julorbi3.3 <- feols(c(trust_pres, performance_pres) ~ postJulorbi_donut + bono, 
                    data=data_eb_fullsample_donut, weights=~weights) 

#### Full sample (N=796)

julorbi4.1 <- feols(c(trust_pres, performance_pres) ~ postJulorbi + bono, 
                    data=data) 
julorbi4.2 <- feols(c(trust_pres, performance_pres) ~ postJulorbi + 
                      vote2020_inc + age + remittance_quota + 
                      gender + education + urbrur + urbrur_from + bono, data=data) 
julorbi4.3 <- feols(c(trust_pres, performance_pres) ~ postJulorbi + bono, 
                    data=data_eb_fullsample, weights=~weights)


uesd_results_main <- c(julorbi1.1, julorbi1.2, julorbi1.3, 
                       julorbi2.1, julorbi2.2, julorbi2.3,
                       julorbi3.1, julorbi3.2, julorbi3.3,
                       julorbi4.1, julorbi4.2, julorbi4.3)

## Collate dataset

julorbi_trust_df <- map_df(uesd_results_main, broom::tidy, .id="model") %>%
  filter(term %in% c("postJulorbi2days", "postJulorbi3days", "postJulorbi", "postJulorbi_donut")) %>%
  mutate(conf.low95 = estimate - 1.96*std.error,
         conf.high95 = estimate + 1.96*std.error,
         conf.low90 = estimate - 1.68*std.error,
         conf.high90 = estimate + 1.68*std.error,
         outcome = rep(c("Trust", "Approval"), 12),
         group = ifelse(term == "postJulorbi", "Full sample ex. first protest day\n(N=802)", 
                 ifelse(term == "postJulorbi_donut", "Full sample ex. all protest days\n(N=632)", 
                 ifelse(term == "postJulorbi3days", "+/-3 days \n(N=515)", 
                        "+/-2 days \n(N=343)"))), 
         spec = rep(c("Baseline", "Baseline", 
                      "Covariates", "Covariates",
                      "Entropy balancing", "Entropy balancing"), 4)) 

```

```{r results-baseline-table-sm}

setFixest_dict(c(postJulorbi2days = "Post period", 
                 postJulorbi3days = "Post period",
                 postJulorbi_donut = "Post period",
                 postJulorbi = "Post period", 
                 trust_pres = "Trust in the President",
                 performance_pres = "Approve President's performance", 
                 vote2020_incGovt = "2020 vote (Govt)", 
                 vote2020_incOpp = "2020 vote (Opp)",
                 `vote2020_incNon-voter` = "2020 vote (Non-voter)",
                 vote2020_inc = "2020 vote",
                 age = "Age", 
                 remittance_quota = "Remittances", 
                 genderMale = "Gender (male)",
                 educationPrimary = "Education (Primary)",
                 educationSecondary = "Education (Secondary)",
                 educationUniversity = "Education (University)",
                 urbrurUrban = "Urban", 
                 urbrur_fromUrban = "From urban", 
                 bono1 = "Bono region", 
                 bono = "Bono region",
                 placebo_treat = "Placebo treatment group",
                 socmedia_week = "Use weekly", 
                 discuss_politics_bin = "Discuss politics",
                 trust_police = "Police", 
                 trust_parl = "Parliament", 
                 trust_officials = "Officials", 
                 trust_ec = "EC", 
                 handle_economy = "Economy", 
                 handle_inflation = "Inflation", 
                 handle_health = "Healthcare", 
                 handle_education = "Education", 
                 handle_corruption = "Corruption",
                 trust_rel = "Relatives",
                 trust_others = "Other people",
                 trust_neighbours = "Neighbours",
                 performance_mp = "Approve MP's performance"))


maintab1 <- etable(julorbi1.1[1], julorbi1.2[1], julorbi1.3[1], 
                   julorbi2.1[1], julorbi2.2[1], julorbi2.3[1],
                   julorbi3.1[1], julorbi3.2[1], julorbi3.3[1],
                   julorbi4.1[1], julorbi4.2[1], julorbi4.3[1],
       title = "Main results (Trust in the President)",
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, "3 day bandwidth" = 3,
                                        "Full sample (ex. protest days)" = 3, "Full sample" = 3)),
       keep = "Post period",
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

maintab2 <- etable(julorbi1.1[2], julorbi1.2[2], julorbi1.3[2], 
                   julorbi2.1[2], julorbi2.2[2], julorbi2.3[2],
                   julorbi3.1[2], julorbi3.2[2], julorbi3.3[2],
                   julorbi4.1[2], julorbi4.2[2], julorbi4.3[2],
       title = "Main results II (Presidential approval)",
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, "3 day bandwidth" = 3,
                                        "Full sample (ex. protest days)" = 3, "Full sample" = 3)),
       keep = "Post period",
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

```

```{r main-results-tabs, results="asis"}

maintab1
maintab2

```

\clearpage

# Partisan heterogeneity {#partisanhet}

We next present results broken down by vote choice in the previous (2020) general election. We present the marginal effect of the protest for each subgroup of interest, taken from an interactive specification. As can be seen, our main positive findings are driven by those who voted for the governing party.

```{r results-partisanship-sm}

### Run specifications

data <- data %>% mutate(vote2020_inc = ifelse(is.na(vote2020_inc) == TRUE, 
                                              "Non-voter", vote2020_inc))

###### Trust

## 2 days
partisan1.1 <- feols(trust_pres ~ i(vote2020_inc, postJulorbi2days) + vote2020_inc + bono, data=data) ## Baseline

partisan1.2 <- feols(trust_pres ~ i(vote2020_inc, postJulorbi2days) + vote2020_inc + age + remittance_quota + 
                      gender + education + 
                       urbrur + urbrur_from + 
                       bono, data=data) ## With wider covariates

partisan1.3 <- feols(trust_pres ~ i(vote2020_inc, postJulorbi2days) + 
                       vote2020_inc + bono, 
                     data=data_eb_2days, weights=~weights) 

## 3 days
partisan2.1 <- feols(trust_pres ~ i(vote2020_inc, postJulorbi3days) + 
                       vote2020_inc + bono, data=data) ## Baseline

partisan2.2 <- feols(trust_pres ~ i(vote2020_inc, postJulorbi3days) + 
                       vote2020_inc + age + remittance_quota + 
                      gender + education + 
                       urbrur + urbrur_from + 
                       bono, data=data) ## With wider covariates

partisan2.3 <- feols(trust_pres ~ i(vote2020_inc, postJulorbi3days) + 
                       vote2020_inc + bono, 
                     data=data_eb_3days, weights=~weights) 

## Full (ex protest days)
partisan3.1 <- feols(trust_pres ~ i(vote2020_inc, postJulorbi_donut) + 
                       vote2020_inc + bono, data=data) ## Baseline

partisan3.2 <- feols(trust_pres ~ i(vote2020_inc, postJulorbi_donut) + 
                       vote2020_inc + age + remittance_quota + 
                       gender + education + 
                       urbrur + urbrur_from + 
                       bono, data=data) ## With wider covariates

partisan3.3 <- feols(trust_pres ~ i(vote2020_inc, postJulorbi_donut) + 
                       vote2020_inc + bono, 
                     data=data_eb_fullsample_donut, weights=~weights) 

## Full
partisan4.1 <- feols(trust_pres ~ i(vote2020_inc, postJulorbi) + 
                       vote2020_inc + bono, data=data) ## Baseline

partisan4.2 <- feols(trust_pres ~ i(vote2020_inc, postJulorbi) + 
                       vote2020_inc + age + remittance_quota + 
                       gender + education + 
                       urbrur + urbrur_from + 
                       bono, data=data) ## With wider covariates

partisan4.3 <- feols(trust_pres ~ i(vote2020_inc, postJulorbi) + 
                       vote2020_inc + bono, 
                     data=data_eb_fullsample, weights=~weights) 


###### Approval

## 2 days
partisan5.1 <- feols(performance_pres ~ i(vote2020_inc, postJulorbi2days) + 
                       vote2020_inc + bono, data=data) ## Baseline

partisan5.2 <- feols(performance_pres ~ i(vote2020_inc, postJulorbi2days) + 
                       vote2020_inc + age + remittance_quota + 
                       gender + education + 
                       urbrur + urbrur_from + 
                       bono, data=data) ## With wider covariates

partisan5.3 <- feols(trust_pres ~ i(vote2020_inc, postJulorbi2days) + 
                       vote2020_inc + bono, 
                     data=data_eb_2days, weights=~weights)

## 3 days
partisan6.1 <- feols(performance_pres ~ i(vote2020_inc, postJulorbi3days) + 
                       vote2020_inc + bono, data=data) ## Baseline

partisan6.2 <- feols(performance_pres ~ i(vote2020_inc, postJulorbi3days) + 
                       vote2020_inc + age + remittance_quota + 
                       gender + education + 
                       urbrur + urbrur_from + 
                       bono, data=data) ## With wider covariates

partisan6.3 <- feols(performance_pres ~ i(vote2020_inc, postJulorbi3days) + 
                       vote2020_inc + age + remittance_quota + 
                       gender + education + 
                       urbrur + urbrur_from + 
                       bono, 
                     data=data_eb_3days, weights=~weights) 

## Full (ex protest days)

partisan7.1 <- feols(performance_pres ~ i(vote2020_inc, postJulorbi_donut) + 
                       vote2020_inc + bono, data=data) ## Baseline

partisan7.2 <- feols(performance_pres ~ i(vote2020_inc, postJulorbi_donut) + 
                       vote2020_inc + age + remittance_quota + 
                       gender + education + 
                       urbrur + urbrur_from + 
                       bono, data=data) ## With wider covariates

partisan7.3 <- feols(performance_pres ~ i(vote2020_inc, postJulorbi_donut) + 
                       vote2020_inc + bono, 
                     data=data_eb_fullsample_donut, weights=~weights) 

## Full
partisan8.1 <- feols(performance_pres ~ i(vote2020_inc, postJulorbi) + 
                       vote2020_inc + bono, data=data) ## Baseline

partisan8.2 <- feols(performance_pres ~ i(vote2020_inc, postJulorbi) + 
                       vote2020_inc + age + remittance_quota + 
                       gender + education + 
                       urbrur + urbrur_from + 
                       bono, data=data) ## With wider covariates

partisan8.3 <- feols(performance_pres ~ i(vote2020_inc, postJulorbi) + 
                       vote2020_inc + bono, 
                     data=data_eb_fullsample, weights=~weights) 

```

```{r partisanship tables-sm}


partisantab1 <- etable(partisan1.1, partisan1.2, partisan1.3, 
                       partisan2.1, partisan2.2, partisan2.3,
       title = "Partisan heterogeneity results I (Trust in the President)",
       
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, 
                                        "3 day bandwidth" = 3)),
       keep = c("Post period", "2020 vote"),
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

partisantab2 <- etable(partisan3.1, partisan3.2, partisan3.3, 
                       partisan4.1, partisan4.2, partisan4.3,
       title = "Partisan heterogeneity results II (Trust in the President)",
       
       headers = list("^:_:Type" = list("Full sample (ex. protest days)" = 3, 
                                        "Full sample" = 3)),
       keep = c("Post period", "2020 vote"),
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

partisantab3 <- etable(partisan5.1, partisan5.2, partisan5.3, 
                       partisan6.1, partisan6.2, partisan6.3,
       title = "Partisan heterogeneity results III (Presidential approval)",
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, "3 day bandwidth" = 3)),
       keep = c("Post period", "2020 vote"),
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

partisantab4 <- etable(partisan7.1, partisan7.2, partisan7.3, 
                       partisan8.1, partisan8.2, partisan8.3,
       title = "Partisan heterogeneity results IV (Presidential approval)",
       headers = list("^:_:Type" = list("Full sample (ex. protest days)" = 3, 
                                        "Full sample" = 3)),
       keep = c("Post period", "2020 vote"),
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

```

```{r full-partisan-tables, results="asis"}

partisantab1
partisantab2
partisantab3
partisantab4

```

\clearpage

# Robustness I: Independence

## Balance check (full data)

The tables below present results from a series of bivariate balance specifications. There is some evidence of imbalance, which we discuss in the main text. As a result, we include covariate-adjusted specifications when presenting our main findings. 

```{r covariate-plot-bivariate-sm, results="asis"}

### Balance checks

data_bal <- data %>% mutate(postJulorbi_donut = ifelse(duringJulorbi == 1, NA, postJulorbi),
                       
                        GA = ifelse(region == "Greater Accra", 1, 0),
                        bono = ifelse(region == "Bono", 1, 0)) %>%
  mutate(age_std = as.numeric(scale(age)),
         male_bin = ifelse(gender == "Male", 1, 0),
         urbrur_bin = ifelse(urbrur == "Urban", 1, 0), 
         urbrur_from_bin = ifelse(urbrur_from == "Urban", 1, 0),
         education_none = ifelse(education == "None", 1, 0),
         education_school = ifelse(education %in% c("Primary", "Secondary"), 1, 0),
         education_university = ifelse(education == "University", 1, 0), 
         govt_bin = ifelse(vote2020_inc == "Govt", 1, 0),
         opp_bin = ifelse(vote2020_inc == "Opp", 1, 0),
         nonvote_bin = ifelse(vote2020_inc == "Non-voter", 1, 0))

data_ga <- data_bal %>% filter(bono == "0")
data_bono <- data_bal %>% filter(bono == "1")

balance1ga <- feols(c(age_std, remittance_quota, male_bin,
        education_none, education_school, education_university,
        govt_bin, nonvote_bin,
        urbrur_bin, urbrur_from_bin
        ) ~ postJulorbi, data=data_ga)

balance2ga <- feols(c(age_std, remittance_quota, male_bin,
        education_none, education_school, education_university,
        govt_bin, nonvote_bin,
        urbrur_bin, urbrur_from_bin
        ) ~ postJulorbi_donut, data=data_ga)

balance3ga <- feols(c(age_std, remittance_quota, male_bin,
        education_none, education_school, education_university,
        govt_bin, nonvote_bin,
        urbrur_bin, urbrur_from_bin
        ) ~ postJulorbi3days, data=data_ga)

balance4ga <- feols(c(age_std, remittance_quota, male_bin,
        education_none, education_school, education_university,
        govt_bin, nonvote_bin,
        urbrur_bin, urbrur_from_bin
        ) ~ postJulorbi2days, data=data_ga)

balance1bono <- feols(c(age_std, remittance_quota, male_bin,
        education_none, education_school, education_university,
        govt_bin, nonvote_bin,
        urbrur_bin, urbrur_from_bin
        ) ~ postJulorbi, data=data_bono)

balance2bono <- feols(c(age_std, remittance_quota, male_bin,
        education_none, education_school, education_university,
        govt_bin, nonvote_bin,
        urbrur_bin, urbrur_from_bin
        ) ~ postJulorbi_donut, data=data_bono)

balance3bono <- feols(c(age_std, remittance_quota, male_bin,
        education_none, education_school, education_university,
        govt_bin, nonvote_bin,
        urbrur_bin, urbrur_from_bin
        ) ~ postJulorbi3days, data=data_bono)

balance4bono <- feols(c(age_std, remittance_quota, male_bin,
        education_none, education_school, education_university,
        govt_bin, nonvote_bin,
        urbrur_bin, urbrur_from_bin
        ) ~ postJulorbi2days, data=data_bono)


## Make tables

## Make graph

balance_list <- c(balance1ga, balance2ga, balance3ga, balance4ga,
                  balance1bono, balance2bono, balance3bono, balance4bono)

balance_df <- map_df(balance_list, broom::tidy, .id="model") %>%
  filter(term != "(Intercept)") %>%
  mutate(conf.low = estimate - 1.96*std.error,
         conf.high = estimate + 1.96*std.error,
         sample = ifelse(term == "postJulorbi", "Full ex. first protest day", 
                  ifelse(term == "postJulorbi_donut", "Full ex. all protest days", 
                  ifelse(term == "postJulorbi3days", "3 day bandwidth pre/post", 
                         "2 day bandwidth pre/post"))),
         outcome = rep(c("Age (standardised)", "Remittances",
                         "Gender (male)", 
                         "No formal education", "Primary/secondary education", "University education",
                         "Voted Govt", "Turnout",
                         "Urban", 
                         "Born urban"), 8), 
         region = rep(c("Greater Accra", "Bono"), each=40)) %>%
  rename(Outcome = outcome, 
         Estimate = estimate, 
         'Standard error' = std.error)

balance_df_bono1 <- balance_df %>% 
  filter(region == "Bono") %>% filter(sample == "2 day bandwidth pre/post") %>%
  select(Outcome, Estimate, 'Standard error') %>%
  mutate_at(vars(Estimate, 'Standard error'), round, 3)

balance_df_bono2 <- balance_df %>% 
  filter(region == "Bono") %>% filter(sample == "3 day bandwidth pre/post") %>%
  select(Outcome, Estimate, 'Standard error') %>%
  mutate_at(vars(Estimate, 'Standard error'), round, 3)

balance_df_bono3 <- balance_df %>% 
  filter(region == "Bono") %>% filter(sample == "Full ex. all protest days") %>% 
  select(Outcome, Estimate, 'Standard error') %>%
  mutate_at(vars(Estimate, 'Standard error'), round, 3)

balance_df_bono4 <- balance_df %>% 
  filter(region == "Bono") %>% filter(sample == "Full ex. first protest day") %>%
  select(Outcome, Estimate, 'Standard error') %>%
  mutate_at(vars(Estimate, 'Standard error'), round, 3)

balance_df_ga1 <- balance_df %>% 
  filter(region != "Bono") %>% filter(sample == "2 day bandwidth pre/post") %>%
  select(Outcome, Estimate, 'Standard error') %>%
  mutate_at(vars(Estimate, 'Standard error'), round, 3)

balance_df_ga2 <- balance_df %>% 
  filter(region != "Bono") %>% filter(sample == "3 day bandwidth pre/post") %>%
  select(Outcome, Estimate, 'Standard error') %>%
  mutate_at(vars(Estimate, 'Standard error'), round, 3)

balance_df_ga3 <- balance_df %>% 
  filter(region != "Bono") %>% filter(sample == "Full ex. all protest days") %>% 
  select(Outcome, Estimate, 'Standard error') %>%
  mutate_at(vars(Estimate, 'Standard error'), round, 3)

balance_df_ga4 <- balance_df %>% 
  filter(region != "Bono") %>% filter(sample == "Full ex. first protest day") %>%
  select(Outcome, Estimate, 'Standard error') %>%
  mutate_at(vars(Estimate, 'Standard error'), round, 3)


balance_df_table_bono <-
  rbind(c("2 day bandwidth", "", "", ""), balance_df_bono1, 
        c("3 day bandwidth", "", "", ""), balance_df_bono2, 
        c("Full ex. protest days", "", "", ""), balance_df_bono3, 
        c("Full ex. first protest day", "", "", ""), balance_df_bono4)

balance_df_table_ga <-
  rbind(c("2 day bandwidth", "", "", ""), balance_df_ga1, 
        c("3 day bandwidth", "", "", ""), balance_df_ga2, 
        c("Full ex. protest days", "", "", ""), balance_df_ga3, 
        c("Full ex. first protest day", "", "", ""), balance_df_ga4)

balance_df_table <- cbind(balance_df_table_bono, balance_df_table_ga)

kable(balance_df_table, format = "latex", booktabs = TRUE, 
      digits=3, 
      linesep = c("", "", "", "", "", "", "", "", "", "", "\\addlinespace"), 
      caption = "Balance check full results") %>% 
  row_spec(c(0,1,12,23,34), bold=T) %>%
  kable_styling(latex_options = "hold_position", 
                font_size = 7) %>%
  add_header_above(c("Bono region" = 3, "Greater Accra region" = 3))

```

\clearpage 

## Balance checks by party 

The tables below present results from balance checks *within* parties, showing that similar types of government and opposition voter are interviewed before and after the protest.

```{r partisan-characteristics-pre-post-sm, results="asis"}

## Check whether partisans before/after share comparable characteristics
## i.e. guard against risk that "really strong" partisans are just more likely to take part afterwards

data_npp <- data %>% filter(vote2020_inc == "Govt") 
data_ndc <- data %>% filter(vote2020_inc == "Opp") 

### Balance checks

data_bal_npp <- data_npp %>% mutate(postJulorbi_donut = ifelse(duringJulorbi == 1, NA, postJulorbi),
                         
                        GA = ifelse(region == "Greater Accra", 1, 0),
                        bono = ifelse(region == "Bono", 1, 0)) %>%
  mutate(age_std = as.numeric(scale(age)),
         male_bin = ifelse(gender == "Male", 1, 0),
         urbrur_bin = ifelse(urbrur == "Urban", 1, 0), 
         urbrur_from_bin = ifelse(urbrur_from == "Urban", 1, 0),
         education_none = ifelse(education == "None", 1, 0),
         education_school = ifelse(education %in% c("Primary", "Secondary"), 1, 0),
         education_university = ifelse(education == "University", 1, 0))

data_bal_ndc <- data_ndc %>% mutate(postJulorbi_donut = ifelse(duringJulorbi == 1, NA, postJulorbi),
                        
                        GA = ifelse(region == "Greater Accra", 1, 0),
                        bono = ifelse(region == "Bono", 1, 0)) %>%
  mutate(age_std = as.numeric(scale(age)),
         male_bin = ifelse(gender == "Male", 1, 0),
         urbrur_bin = ifelse(urbrur == "Urban", 1, 0), 
         urbrur_from_bin = ifelse(urbrur_from == "Urban", 1, 0),
         education_none = ifelse(education == "None", 1, 0),
         education_school = ifelse(education %in% c("Primary", "Secondary"), 1, 0),
         education_university = ifelse(education == "University", 1, 0))

## Seperate by a) region, b) party

data_bal_npp_bono <- data_bal_npp %>% filter(region == "Bono")
data_bal_npp_ga <- data_bal_npp %>% filter(region != "Bono")
data_bal_ndc_bono <- data_bal_ndc %>% filter(region == "Bono")
data_bal_ndc_ga <- data_bal_ndc %>% filter(region != "Bono")

### Government voters

balance1_npp_ga <- feols(c(age_std, remittance_quota, male_bin,
        education_none, education_school, education_university,
        urbrur_bin, urbrur_from_bin
        ) ~ postJulorbi, data=data_bal_npp_ga)

balance2_npp_ga <- feols(c(age_std, remittance_quota, male_bin,
        education_none, education_school, education_university,
        urbrur_bin, urbrur_from_bin
        ) ~ postJulorbi_donut, data=data_bal_npp_ga)

balance3_npp_ga <- feols(c(age_std, remittance_quota, male_bin,
        education_none, education_school, education_university,
        urbrur_bin, urbrur_from_bin
        ) ~ postJulorbi3days, data=data_bal_npp_ga)

balance4_npp_ga <- feols(c(age_std, remittance_quota, male_bin,
        education_none, education_school, education_university,
        urbrur_bin, urbrur_from_bin
        ) ~ postJulorbi2days, data=data_bal_npp_ga)

balance1_npp_bono <- feols(c(age_std, remittance_quota, male_bin,
        education_none, education_school, education_university,
        urbrur_bin, urbrur_from_bin
        ) ~ postJulorbi, data=data_bal_npp_bono)

balance2_npp_bono <- feols(c(age_std, remittance_quota, male_bin,
        education_none, education_school, education_university,
        urbrur_bin, urbrur_from_bin
        ) ~ postJulorbi_donut, data=data_bal_npp_bono)

balance3_npp_bono <- feols(c(age_std, remittance_quota, male_bin,
        education_none, education_school, education_university,
        urbrur_bin, urbrur_from_bin
        ) ~ postJulorbi3days, data=data_bal_npp_bono)

balance4_npp_bono <- feols(c(age_std, remittance_quota, male_bin,
        education_none, education_school, education_university,
        urbrur_bin, urbrur_from_bin
        ) ~ postJulorbi2days, data=data_bal_npp_bono)


### Opposition voters

balance1_ndc_ga <- feols(c(age_std, remittance_quota, male_bin,
        education_none, education_school, education_university,
        urbrur_bin, urbrur_from_bin
        ) ~ postJulorbi, data=data_bal_ndc_ga)

balance2_ndc_ga <- feols(c(age_std, remittance_quota, male_bin,
        education_none, education_school, education_university,
        urbrur_bin, urbrur_from_bin
        ) ~ postJulorbi_donut, data=data_bal_ndc_ga)

balance3_ndc_ga <- feols(c(age_std, remittance_quota, male_bin,
        education_none, education_school, education_university,
        urbrur_bin, urbrur_from_bin
        ) ~ postJulorbi3days, data=data_bal_ndc_ga)

balance4_ndc_ga <- feols(c(age_std, remittance_quota, male_bin,
        education_none, education_school, education_university,
        urbrur_bin, urbrur_from_bin
        ) ~ postJulorbi2days, data=data_bal_ndc_ga)

balance1_ndc_bono <- feols(c(age_std, remittance_quota, male_bin,
        education_none, education_school, education_university,
        urbrur_bin, urbrur_from_bin
        ) ~ postJulorbi, data=data_bal_ndc_bono)

balance2_ndc_bono <- feols(c(age_std, remittance_quota, male_bin,
        education_none, education_school, education_university,
        urbrur_bin, urbrur_from_bin
        ) ~ postJulorbi_donut, data=data_bal_ndc_bono)

balance3_ndc_bono <- feols(c(age_std, remittance_quota, male_bin,
        education_none, education_school, education_university,
        urbrur_bin, urbrur_from_bin
        ) ~ postJulorbi3days, data=data_bal_ndc_bono)

balance4_ndc_bono <- feols(c(age_std, remittance_quota, male_bin,
        education_none, education_school, education_university,
        urbrur_bin, urbrur_from_bin
        ) ~ postJulorbi2days, data=data_bal_ndc_bono)


## Make tables

## Make graph

balance_list <- c(balance1_npp_ga, balance2_npp_ga, balance3_npp_ga, balance4_npp_ga,
                  balance1_npp_bono, balance2_npp_bono, balance3_npp_bono, balance4_npp_bono,
                  balance1_ndc_ga, balance2_ndc_ga, balance3_ndc_ga, balance4_ndc_ga, 
                  balance1_ndc_bono, balance2_ndc_bono, balance3_ndc_bono, balance4_ndc_bono)

balance_df <- map_df(balance_list, broom::tidy, .id="model") %>%
  filter(term != "(Intercept)") %>%
  mutate(conf.low = estimate - 1.96*std.error,
         conf.high = estimate + 1.96*std.error,
         sample = ifelse(term == "postJulorbi", "Full ex. first protest day", 
                  ifelse(term == "postJulorbi_donut", "Full ex. all protest days", 
                  ifelse(term == "postJulorbi3days", "3 day bandwidth pre/post", 
                         "2 day bandwidth pre/post"))),
         outcome = rep(c("Age", "Remittances",
                         "Gender (male)", 
                         "No formal\neducation", "Primary or\nsecondary", 
                         "University",
                         "Urban", 
                         "Born urban"), 16), 
         party = rep(c("Govt", "Opp"), each=64), 
         region = rep(c("Greater Accra", "Bono", "Greater Accra", "Bono"), each=32)) %>%
  rename(Outcome = outcome, 
         Estimate = estimate, 
         'Standard error' = std.error)


### Make tables

####### Government

balance_df_bono_npp1 <- balance_df %>% 
  filter(region == "Bono", party == "Govt") %>% filter(sample == "2 day bandwidth pre/post") %>%
  select(Outcome, Estimate, 'Standard error') %>%
  mutate_at(vars(Estimate, 'Standard error'), round, 3)

balance_df_bono_npp2 <- balance_df %>% 
  filter(region == "Bono", party == "Govt") %>% filter(sample == "3 day bandwidth pre/post") %>%
  select(Outcome, Estimate, 'Standard error') %>%
  mutate_at(vars(Estimate, 'Standard error'), round, 3)

balance_df_bono_npp3 <- balance_df %>% 
  filter(region == "Bono", party == "Govt") %>% filter(sample == "Full ex. all protest days") %>% 
  select(Outcome, Estimate, 'Standard error') %>%
  mutate_at(vars(Estimate, 'Standard error'), round, 3)

balance_df_bono_npp4 <- balance_df %>% 
  filter(region == "Bono", party == "Govt") %>% filter(sample == "Full ex. first protest day") %>%
  select(Outcome, Estimate, 'Standard error') %>%
  mutate_at(vars(Estimate, 'Standard error'), round, 3)

balance_df_ga_npp1 <- balance_df %>% 
  filter(region != "Bono", party == "Govt") %>% filter(sample == "2 day bandwidth pre/post") %>%
  select(Outcome, Estimate, 'Standard error') %>%
  mutate_at(vars(Estimate, 'Standard error'), round, 3)

balance_df_ga_npp2 <- balance_df %>% 
  filter(region != "Bono", party == "Govt") %>% filter(sample == "3 day bandwidth pre/post") %>%
  select(Outcome, Estimate, 'Standard error') %>%
  mutate_at(vars(Estimate, 'Standard error'), round, 3)

balance_df_ga_npp3 <- balance_df %>% 
  filter(region != "Bono", party == "Govt") %>% filter(sample == "Full ex. all protest days") %>% 
  select(Outcome, Estimate, 'Standard error') %>%
  mutate_at(vars(Estimate, 'Standard error'), round, 3)

balance_df_ga_npp4 <- balance_df %>% 
  filter(region != "Bono", party == "Govt") %>% filter(sample == "Full ex. first protest day") %>%
  select(Outcome, Estimate, 'Standard error') %>%
  mutate_at(vars(Estimate, 'Standard error'), round, 3)

balance_df_table_bono_npp <-
  rbind(c("2 day bandwidth", "", "", ""), balance_df_bono_npp1, 
        c("3 day bandwidth", "", "", ""), balance_df_bono_npp2, 
        c("Full ex. protest days", "", "", ""), balance_df_bono_npp3, 
        c("Full ex. first protest day", "", "", ""), balance_df_bono_npp4)

balance_df_table_ga_npp <-
  rbind(c("2 day bandwidth", "", "", ""), balance_df_ga_npp1, 
        c("3 day bandwidth", "", "", ""), balance_df_ga_npp2, 
        c("Full ex. protest days", "", "", ""), balance_df_ga_npp3, 
        c("Full ex. first protest day", "", "", ""), balance_df_ga_npp4)

balance_df_table_npp <- cbind(balance_df_table_bono_npp, balance_df_table_ga_npp)

kable(balance_df_table_npp, format = "latex", booktabs = TRUE, 
      digits=3, 
      linesep = c("", "", "", "", "", "", "", "", "\\addlinespace"), 
      caption = "Balance check full results (Government voters)") %>% 
  row_spec(c(0,1,10,19,28), bold=T) %>%
  kable_styling(latex_options = "hold_position", 
                font_size = 7) %>%
  add_header_above(c("Bono region" = 3, "Greater Accra region" = 3))


#### Opposition

balance_df_bono_ndc1 <- balance_df %>% 
  filter(region == "Bono", party == "Opp") %>% filter(sample == "2 day bandwidth pre/post") %>%
  select(Outcome, Estimate, 'Standard error') %>%
  mutate_at(vars(Estimate, 'Standard error'), round, 3)

balance_df_bono_ndc2 <- balance_df %>% 
  filter(region == "Bono", party == "Opp") %>% filter(sample == "3 day bandwidth pre/post") %>%
  select(Outcome, Estimate, 'Standard error') %>%
  mutate_at(vars(Estimate, 'Standard error'), round, 3)

balance_df_bono_ndc3 <- balance_df %>% 
  filter(region == "Bono", party == "Opp") %>% filter(sample == "Full ex. all protest days") %>% 
  select(Outcome, Estimate, 'Standard error') %>%
  mutate_at(vars(Estimate, 'Standard error'), round, 3)

balance_df_bono_ndc4 <- balance_df %>% 
  filter(region == "Bono", party == "Opp") %>% filter(sample == "Full ex. first protest day") %>%
  select(Outcome, Estimate, 'Standard error') %>%
  mutate_at(vars(Estimate, 'Standard error'), round, 3)

balance_df_ga_ndc1 <- balance_df %>% 
  filter(region != "Bono", party == "Opp") %>% filter(sample == "2 day bandwidth pre/post") %>%
  select(Outcome, Estimate, 'Standard error') %>%
  mutate_at(vars(Estimate, 'Standard error'), round, 3)

balance_df_ga_ndc2 <- balance_df %>% 
  filter(region != "Bono", party == "Opp") %>% filter(sample == "3 day bandwidth pre/post") %>%
  select(Outcome, Estimate, 'Standard error') %>%
  mutate_at(vars(Estimate, 'Standard error'), round, 3)

balance_df_ga_ndc3 <- balance_df %>% 
  filter(region != "Bono", party == "Opp") %>% filter(sample == "Full ex. all protest days") %>% 
  select(Outcome, Estimate, 'Standard error') %>%
  mutate_at(vars(Estimate, 'Standard error'), round, 3)

balance_df_ga_ndc4 <- balance_df %>% 
  filter(region != "Bono", party == "Opp") %>% filter(sample == "Full ex. first protest day") %>%
  select(Outcome, Estimate, 'Standard error') %>%
  mutate_at(vars(Estimate, 'Standard error'), round, 3)


### Make and print tables

balance_df_table_bono_ndc <-
  rbind(c("2 day bandwidth", "", "", ""), balance_df_bono_ndc1, 
        c("3 day bandwidth", "", "", ""), balance_df_bono_ndc2, 
        c("Full ex. protest days", "", "", ""), balance_df_bono_ndc3, 
        c("Full ex. first protest day", "", "", ""), balance_df_bono_ndc4)

balance_df_table_ga_ndc <-
  rbind(c("2 day bandwidth", "", "", ""), balance_df_ga_ndc1, 
        c("3 day bandwidth", "", "", ""), balance_df_ga_ndc2, 
        c("Full ex. protest days", "", "", ""), balance_df_ga_ndc3, 
        c("Full ex. first protest day", "", "", ""), balance_df_ga_ndc4)

balance_df_table_ndc <- cbind(balance_df_table_bono_ndc, balance_df_table_ga_ndc)

kable(balance_df_table_ndc, format = "latex", booktabs = TRUE, 
      digits=3, 
      linesep = c("", "", "", "", "", "", "", "", "\\addlinespace"), 
      caption = "Balance check full results (Opposition voters)") %>% 
  row_spec(c(0,1,10,19,28), bold=T) %>%
  kable_styling(latex_options = "hold_position", 
                font_size = 7) %>%
  add_header_above(c("Bono region" = 3, "Greater Accra region" = 3))



```

\clearpage

## Unrelated time trends {#timetrends}

We assess time trends in two ways. First, we split the control group at its empirical mean and show that there are no significant differences between each half of the sample. Second, we re-run our main analysis controlling for a linear time trend, representing the interview date. It is unclear how meaningful this test is, given the few individual interview days in our sample (N=12), particularly at 2 and 3 day bandwidths. Nonetheless, the tables below show that including time trends widens confidence intervals at lower bandwidths, but our main findings are robust when using the full sample.

```{r control-empirical-median, results="hide"}

## Filter for control responses, use bigger bandwidth otherwise not enough obs
## And add placebo treatment at empirical median
control <- data %>% filter(postJulorbi == 0) %>%
  arrange(date) %>% ## Put into chronological order
  mutate(count = 1:n(), 
         placebo_treat = ifelse(count > median(count), 1, 0)) ## Split at empirical median
## 117 in each


## Entropy weights for control group

###### Control group sample

data_restrict <- control %>%  ### Remove irrelevant obs (outside bandwidth)
  select(trust_pres, performance_pres, vote2020_inc,
         placebo_treat, age, gender, education, urbrur, region) %>% ### Select controls
  filter_at(vars(trust_pres:region), all_vars(!is.na(.))) %>% ### Remove missing values
  mutate(gender = ifelse(gender == "Male", 1, 0), 
         education = ifelse(education == "None", 1, 
                     ifelse(education == "Primary", 2, 
                     ifelse(education == "Secondary", 3, 4))),
         urbrur = ifelse(urbrur == "Urban", 1, 0)) ## Convert categorical indicators to numbers so can take the mean

Treatment <- data_restrict %>%
  select(placebo_treat) ## i.e. just take the treatment variable

Treatment <- Treatment$placebo_treat

X <- data_restrict %>%
  select(!c(placebo_treat, trust_pres, performance_pres, 
            vote2020_inc, region)) %>% ## i.e. keep everything except treatment (the controls)
  as.matrix() 

eb <- ebalance(Treatment, X)

eb_treat <- data_restrict %>%
  filter(placebo_treat == 1) %>%
  mutate(weights = 1)
eb_con <- data_restrict %>%
  filter(placebo_treat == 0) %>%
  mutate(weights = eb$w)
data_eb_control <- bind_rows(eb_treat, eb_con) %>%
  mutate(bono = ifelse(region == "Bono", 1, 0))



## Run specifications

### Trust President


control1 <- feols(trust_pres ~ placebo_treat + bono, data=control)

control2 <- feols(trust_pres ~ placebo_treat +  
                       vote2020_inc + age + remittance_quota + 
                       gender + education + 
                       urbrur + urbrur_from + 
                       bono, data=control)

control3 <- feols(trust_pres ~ placebo_treat + bono, data=data_eb_control, weights=~weights)


### Performance President


control4 <- feols(performance_pres ~ placebo_treat + bono, data=control)

control5 <- feols(performance_pres ~ placebo_treat +  
                       vote2020_inc + age + remittance_quota + 
                       gender + education + 
                       urbrur + urbrur_from + 
                       bono, data=control)

control6 <- feols(performance_pres ~ placebo_treat + bono, 
                  data=data_eb_control, weights=~weights)


## Make table


empiricalmean_tab <- etable(control1, control2, control3, 
                 control4, control5, control6,
       title = "Splitting control group at empirical median (placebo test)",
       keep = "Placebo treatment group",
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)


```

```{r empirical-median-tabs, results="asis"}

empiricalmean_tab

```

```{r results-control-tt}

## Trust in politics 

#### 2 day bandwidth (N=336)

data <- data %>% mutate(bono = as.factor(bono))

julorbi1.1 <- feols(c(trust_pres, performance_pres) ~ postJulorbi2days + time_trend + bono, data=data) ## Baseline
julorbi1.2 <- feols(c(trust_pres, performance_pres) ~ postJulorbi2days + time_trend + 
                      age + gender + education + remittance_quota + vote2020_inc + 
                      urbrur_from + urbrur + bono, data=data) ## With wider covariates
julorbi1.3 <- feols(c(trust_pres, performance_pres) ~ postJulorbi2days + time_trend + bono, data=data_eb_2days, weights=~weights) 


#### 3 day bandwidth (N=508)

julorbi2.1 <- feols(c(trust_pres, performance_pres) ~ postJulorbi3days + time_trend + time_trend + bono, 
                    data=data) ## Baseline
julorbi2.2 <- feols(c(trust_pres, performance_pres) ~ postJulorbi3days + + time_trend + 
                      age + gender + education + remittance_quota + vote2020_inc + 
                      urbrur_from + urbrur + bono, data=data) ## With wider covariates
julorbi2.3 <- feols(c(trust_pres, performance_pres) ~ postJulorbi3days + time_trend + bono, 
                    data=data_eb_3days, weights=~weights) 


#### Full sample excl. protest days (N=627)

julorbi3.1 <- feols(c(trust_pres, performance_pres) ~ postJulorbi_donut + time_trend + bono, data=data) ## Baseline
julorbi3.2 <- feols(c(trust_pres, performance_pres) ~ postJulorbi_donut + + time_trend + 
                      age + gender + education + remittance_quota + vote2020_inc + 
                      urbrur_from + urbrur + bono, data=data) ## With wider covariates
julorbi3.3 <- feols(c(trust_pres, performance_pres) ~ postJulorbi_donut + time_trend + bono, 
                    data=data_eb_fullsample_donut, weights=~weights) 

#### Full sample (N=796)

julorbi4.1 <- feols(c(trust_pres, performance_pres) ~ postJulorbi + time_trend + bono, data=data) ## Baseline
julorbi4.2 <- feols(c(trust_pres, performance_pres) ~ postJulorbi + + time_trend + 
                      age + gender + education + remittance_quota + vote2020_inc + 
                      urbrur_from + urbrur + bono, data=data) ## With wider covariates
julorbi4.3 <- feols(c(trust_pres, performance_pres) ~ postJulorbi + time_trend + bono, 
                    data=data_eb_fullsample, weights=~weights)

```

```{r results-baseline-table-tts, results="asis"}

setFixest_dict(c(postJulorbi2days = "Post period", 
                 postJulorbi3days = "Post period",
                 postJulorbi_donut = "Post period",
                 postJulorbi = "Post period", 
                 trust_pres = "Trust in the President",
                 performance_pres = "Approve President's performance"))


maintab1_tt <- etable(julorbi1.1[1], julorbi1.2[1], julorbi1.3[1], 
                      julorbi2.1[1], julorbi2.2[1], julorbi2.3[1],
                      julorbi3.1[1], julorbi3.2[1], julorbi3.3[1], 
                      julorbi4.1[1], julorbi4.2[1], julorbi4.3[1],
       title = "Main results with linear time trend (Trust in the President)",
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, "3 day bandwidth" = 3,
                                        "Full sample (ex. protest days)" = 3, 
                                        "Full sample" = 3)),
       keep = "Post period",
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

maintab2_tt <- etable(julorbi1.1[2], julorbi1.2[2], julorbi1.3[2], 
                      julorbi2.1[2], julorbi2.2[2], julorbi2.3[2],
                      julorbi3.1[2], julorbi3.2[2], julorbi3.3[2], 
                      julorbi4.1[2], julorbi4.2[2], julorbi4.3[2],
       title = "Main results with linear time trend (Presidential approval)",
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, "3 day bandwidth" = 3,
                                        "Full sample (ex. protest days)" = 3, 
                                        "Full sample" = 3)),
       keep = "Post period",
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)



maintab1_tt
maintab2_tt


```


\clearpage 

## Compliance I (access to information) {#complianceI}

The results below present marginal effects among respondents who a) use social media at least weekly (vs not) and b) discuss politics sometimes or often (vs never). These proxy access to the protest through online platforms and offline networks.

At higher bandwidths, our findings are statistically significant at both levels of either variable. Point estimates are generally larger among social media users/those who discuss politics, but the difference between each level is itself not significant. 

These results reaffirm our claims about the salience of the protest. Even among those who do not use social media or regularly discuss politics, we still observe positive effects. In other words, our results are unlikely driven by an unrepresentative subset of compliers.

```{r socialmedia, results="asis"}

## Social media

### 2 days

info1.1 <- feols(c(trust_pres, performance_pres) ~ i(socmedia_week, postJulorbi2days) + socmedia_week + 
                   bono, data=data)

info1.2 <- feols(c(trust_pres, performance_pres) ~ i(socmedia_week, postJulorbi2days) + 
                   socmedia_week + age + gender + education + 
                   remittance_quota + vote2020_inc + urbrur + urbrur_from + bono, data=data)

info1.3 <- feols(c(trust_pres, performance_pres) ~ i(socmedia_week, postJulorbi2days) + socmedia_week + bono,
               data=data_eb_2days_info, weights=~weights)

### 3 days

info2.1 <- feols(c(trust_pres, performance_pres) ~ i(socmedia_week, postJulorbi3days) + socmedia_week + bono, data=data)

info2.2 <- feols(c(trust_pres, performance_pres) ~ i(socmedia_week, postJulorbi3days) + 
                  socmedia_week + age + gender + education + 
                   remittance_quota + vote2020_inc + urbrur + urbrur_from + bono, data=data)

info2.3 <- feols(c(trust_pres, performance_pres) ~ i(socmedia_week, postJulorbi3days) + socmedia_week + bono,
               data=data_eb_3days_info, weights=~weights)

### Full ex. all protest days

info3.1 <- feols(c(trust_pres, performance_pres) ~ i(socmedia_week, postJulorbi_donut) + socmedia_week + bono, data=data)

info3.2 <- feols(c(trust_pres, performance_pres) ~ i(socmedia_week, postJulorbi_donut) + 
                   socmedia_week + age + gender + education + 
                   remittance_quota + vote2020_inc + urbrur + urbrur_from + bono, data=data)

info3.3 <- feols(c(trust_pres, performance_pres) ~ i(socmedia_week, postJulorbi_donut) + socmedia_week + bono,
               data=data_eb_fullsample_donut_info, weights=~weights)

### Full ex. first protest day

info4.1 <- feols(c(trust_pres, performance_pres) ~ i(socmedia_week, postJulorbi) + socmedia_week + bono, data=data)

info4.2 <- feols(c(trust_pres, performance_pres) ~ i(socmedia_week, postJulorbi) + 
                   socmedia_week + age + gender + education + 
                   remittance_quota + vote2020_inc + urbrur + urbrur_from + bono, data=data)

info4.3 <- feols(c(trust_pres, performance_pres) ~ i(socmedia_week, postJulorbi) + socmedia_week + bono,
               data=data_eb_fullsample_info, weights=~weights)


## Internet

### 2 days

info5.1 <- feols(c(trust_pres, performance_pres) ~ i(discuss_politics_bin, postJulorbi2days) + 
                   discuss_politics_bin + bono, data=data)

info5.2 <- feols(c(trust_pres, performance_pres) ~ i(discuss_politics_bin, postJulorbi2days) + 
                   discuss_politics_bin + age + gender + education + 
                   remittance_quota + vote2020_inc + urbrur + urbrur_from + bono, data=data)

info5.3 <- feols(c(trust_pres, performance_pres) ~ i(discuss_politics_bin, postJulorbi2days) + 
                   discuss_politics_bin + bono,
               data=data_eb_2days_info, weights=~weights)

### 3 days

info6.1 <- feols(c(trust_pres, performance_pres) ~ i(discuss_politics_bin, postJulorbi3days) +
                    discuss_politics_bin + bono, data=data)

info6.2 <- feols(c(trust_pres, performance_pres) ~ i(discuss_politics_bin, postJulorbi3days) + 
                   discuss_politics_bin + age + gender + education + 
                   remittance_quota + vote2020_inc + urbrur + urbrur_from + bono, data=data)

info6.3 <- feols(c(trust_pres, performance_pres) ~ i(discuss_politics_bin, postJulorbi3days) +
                    discuss_politics_bin + bono,
               data=data_eb_3days_info, weights=~weights)

### Full ex. all protest days

info7.1 <- feols(c(trust_pres, performance_pres) ~ i(discuss_politics_bin, postJulorbi_donut) +
                    discuss_politics_bin + bono, data=data)

info7.2 <- feols(c(trust_pres, performance_pres) ~ i(discuss_politics_bin, postJulorbi_donut) + 
                   discuss_politics_bin + age + gender + education + 
                   remittance_quota + vote2020_inc + urbrur + urbrur_from + bono, data=data)

info7.3 <- feols(c(trust_pres, performance_pres) ~ i(discuss_politics_bin, postJulorbi_donut) +
                    discuss_politics_bin + bono,
               data=data_eb_fullsample_donut_info, weights=~weights)

### Full ex. first protest day

info8.1 <- feols(c(trust_pres, performance_pres) ~ i(discuss_politics_bin, postJulorbi) + 
                    discuss_politics_bin + bono, data=data)

info8.2 <- feols(c(trust_pres, performance_pres) ~ i(discuss_politics_bin, postJulorbi) + 
                   discuss_politics_bin + age + gender + education + 
                   remittance_quota + vote2020_inc + urbrur + urbrur_from + bono, data=data)

info8.3 <- feols(c(trust_pres, performance_pres) ~ i(discuss_politics_bin, postJulorbi) + 
                    discuss_politics_bin + bono,
               data=data_eb_fullsample_info, weights=~weights)


### Make tables

socmedia_tab1 <- etable(info1.1[1], info1.2[1], info1.3[1], 
                        info2.1[1], info2.2[1], info2.3[1],
                        info3.1[1], info3.2[1], info3.3[1], 
                        info4.1[1], info4.2[1], info4.3[1],
       title = "Results by social media exposure (Trust President)",
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, "3 day bandwidth" = 3,
                                        "Full sample (ex. protest days)" = 3,
                                        "Full sample (ex. first protest day)" = 3)),
       keep = c("Post period", "Use weekly"),
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

socmedia_tab2 <- etable(info1.1[2], info1.2[2], info1.3[2], 
                        info2.1[2], info2.2[2], info2.3[2],
                        info3.1[2], info3.2[2], info3.3[2], 
                        info4.1[2], info4.2[2], info4.3[2],
       title = "Results by social media exposure (Presidential approval)",
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, "3 day bandwidth" = 3,
                                        "Full sample (ex. protest days)" = 3,
                                        "Full sample (ex. first protest day)" = 3)),
       keep = c("Post period", "Use weekly"),
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

socmedia_tab3 <- etable(info5.1[1], info5.2[1], info5.3[1], 
                        info6.1[1], info6.2[1], info6.3[1],
                        info7.1[1], info7.2[1], info7.3[1], 
                        info8.1[1], info8.2[1], info8.3[1],
       title = "Results by political discussion (Trust President)",
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, "3 day bandwidth" = 3,
                                        "Full sample (ex. protest days)" = 3,
                                        "Full sample (ex. first protest day)" = 3)),
       keep = c("Post period", "Discuss politics"),
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

socmedia_tab4 <- etable(info5.1[2], info5.2[2], info5.3[2], 
                        info6.1[2], info6.2[2], info6.3[2],
                        info7.1[2], info7.2[2], info7.3[2], 
                        info8.1[2], info8.2[2], info8.3[2],
       title = "Results by political discussion (Presidential approval)",
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, "3 day bandwidth" = 3,
                                        "Full sample (ex. protest days)" = 3,
                                        "Full sample (ex. first protest day)" = 3)),
       keep = c("Post period", "Discuss politics"),
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

socmedia_tab1
socmedia_tab2
socmedia_tab3
socmedia_tab4

```

\clearpage 

## Compliance II (regional heterogeneity) {#region}

The results below present results for Bono and Greater Accra region separately. This halves our sample size, meaning effects are expectedly noisier at lower bandwidths. When using the full sample, however, our main results are robust. Effects are slightly stronger in Bono region and weaker in Greater Accra, particularly for Presidential approval.

These findings are useful from a compliance perspective. While respondents in Greater Accra might be personally affected by the protest, those in Bono are much less likely to be, given the region's remoteness. As such, consistent (indeed stronger) findings in this part of the country point toward an informational mechanism, with the protest representing a shock in the salience of anti-government sentiment.

```{r results-baseline-bono}

data <- data %>% mutate(bono = as.factor(bono))

data_bono <- data %>% filter(region == "Bono")

#### 2 day bandwidth

julorbi1.1 <- feols(c(trust_pres, performance_pres) ~ postJulorbi2days, 
                    data=data_bono) ## Baseline
julorbi1.2 <- feols(c(trust_pres, performance_pres) ~ postJulorbi2days + 
                      vote2020_inc + age + remittance_quota + 
                      gender + education + urbrur + urbrur_from, data=data_bono) ## Covariates
julorbi1.3 <- feols(c(trust_pres, performance_pres) ~ postJulorbi2days, 
                    data=subset(data_eb_2days, bono == "1"), 
                    weights=~weights) # Entropy weights

#### 3 day bandwidth

julorbi2.1 <- feols(c(trust_pres, performance_pres) ~ postJulorbi3days, 
                    data=data_bono)
julorbi2.2 <- feols(c(trust_pres, performance_pres) ~ postJulorbi3days + 
                      vote2020_inc + age + remittance_quota + 
                      gender + education + urbrur + urbrur_from, data=data_bono)
julorbi2.3 <- feols(c(trust_pres, performance_pres) ~ postJulorbi3days, 
                    data=subset(data_eb_3days, bono == "1"), 
                    weights=~weights)


#### Full sample excl. protest days

julorbi3.1 <- feols(c(trust_pres, performance_pres) ~ postJulorbi_donut, 
                    data=data_bono) 
julorbi3.2 <- feols(c(trust_pres, performance_pres) ~ postJulorbi_donut + 
                      vote2020_inc + age + remittance_quota + 
                      gender + education + urbrur + urbrur_from, data=data_bono) 
julorbi3.3 <- feols(c(trust_pres, performance_pres) ~ postJulorbi_donut, 
                    data=subset(data_eb_fullsample_donut, bono == "1"), 
                    weights=~weights) 

#### Full sample

julorbi4.1 <- feols(c(trust_pres, performance_pres) ~ postJulorbi, 
                    data=data_bono) 
julorbi4.2 <- feols(c(trust_pres, performance_pres) ~ postJulorbi + 
                      vote2020_inc + age + remittance_quota + 
                      gender + education + urbrur + urbrur_from + bono, data=data_bono) 
julorbi4.3 <- feols(c(trust_pres, performance_pres) ~ postJulorbi, 
                    data=subset(data_eb_fullsample, bono == "1"), weights=~weights)

```

```{r results-table-bono, results="asis"}


maintab1_bono <- etable(julorbi1.1[1], julorbi1.2[1], julorbi1.3[1], 
                   julorbi2.1[1], julorbi2.2[1], julorbi2.3[1],
                   julorbi3.1[1], julorbi3.2[1], julorbi3.3[1],
                   julorbi4.1[1], julorbi4.2[1], julorbi4.3[1],
       title = "Main results I - Bono region only (Trust in the President)",
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, "3 day bandwidth" = 3,
                                        "Full sample (ex. protest days)" = 3, "Full sample" = 3)),
       keep = "Post period",
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

maintab2_bono <- etable(julorbi1.1[2], julorbi1.2[2], julorbi1.3[2], 
                   julorbi2.1[2], julorbi2.2[2], julorbi2.3[2],
                   julorbi3.1[2], julorbi3.2[2], julorbi3.3[2],
                   julorbi4.1[2], julorbi4.2[2], julorbi4.3[2],
       title = "Main results II - Bono region only (Presidential approval)",
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, "3 day bandwidth" = 3,
                                        "Full sample (ex. protest days)" = 3, "Full sample" = 3)),
       keep = "Post period",
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

```

```{r results-baseline-ga}

data <- data %>% mutate(bono = as.factor(bono))

data_ga <- data %>% filter(region != "Bono")

#### 2 day bandwidth

julorbi1.1 <- feols(c(trust_pres, performance_pres) ~ postJulorbi2days, 
                    data=data_ga) ## Baseline
julorbi1.2 <- feols(c(trust_pres, performance_pres) ~ postJulorbi2days + 
                      vote2020_inc + age + remittance_quota + 
                      gender + education + urbrur + urbrur_from, data=data_ga) ## Covariates
julorbi1.3 <- feols(c(trust_pres, performance_pres) ~ postJulorbi2days, 
                    data=subset(data_eb_2days, bono == "0"), 
                    weights=~weights) # Entropy weights

#### 3 day bandwidth

julorbi2.1 <- feols(c(trust_pres, performance_pres) ~ postJulorbi3days, 
                    data=data_ga)
julorbi2.2 <- feols(c(trust_pres, performance_pres) ~ postJulorbi3days + 
                      vote2020_inc + age + remittance_quota + 
                      gender + education + urbrur + urbrur_from, data=data_ga)
julorbi2.3 <- feols(c(trust_pres, performance_pres) ~ postJulorbi3days, 
                    data=subset(data_eb_3days, bono == "0"), 
                    weights=~weights)


#### Full sample excl. protest days

julorbi3.1 <- feols(c(trust_pres, performance_pres) ~ postJulorbi_donut, 
                    data=data_ga) 
julorbi3.2 <- feols(c(trust_pres, performance_pres) ~ postJulorbi_donut + 
                      vote2020_inc + age + remittance_quota + 
                      gender + education + urbrur + urbrur_from, data=data_ga) 
julorbi3.3 <- feols(c(trust_pres, performance_pres) ~ postJulorbi_donut, 
                    data=subset(data_eb_fullsample_donut, bono == "0"), 
                    weights=~weights) 

#### Full sample

julorbi4.1 <- feols(c(trust_pres, performance_pres) ~ postJulorbi, 
                    data=data_ga) 
julorbi4.2 <- feols(c(trust_pres, performance_pres) ~ postJulorbi + 
                      vote2020_inc + age + remittance_quota + 
                      gender + education + urbrur + urbrur_from + bono, data=data_ga) 
julorbi4.3 <- feols(c(trust_pres, performance_pres) ~ postJulorbi, 
                    data=subset(data_eb_fullsample, bono == "0"), weights=~weights)

```

```{r results-table-ga, results="asis"}


maintab1_ga <- etable(julorbi1.1[1], julorbi1.2[1], julorbi1.3[1], 
                   julorbi2.1[1], julorbi2.2[1], julorbi2.3[1],
                   julorbi3.1[1], julorbi3.2[1], julorbi3.3[1],
                   julorbi4.1[1], julorbi4.2[1], julorbi4.3[1],
       title = "Main results I - Greater Accra region only (Trust in the President)",
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, "3 day bandwidth" = 3,
                                        "Full sample (ex. protest days)" = 3, "Full sample" = 3)),
       keep = "Post period",
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

maintab2_ga <- etable(julorbi1.1[2], julorbi1.2[2], julorbi1.3[2], 
                   julorbi2.1[2], julorbi2.2[2], julorbi2.3[2],
                   julorbi3.1[2], julorbi3.2[2], julorbi3.3[2],
                   julorbi4.1[2], julorbi4.2[2], julorbi4.3[2],
       title = "Main results II - Greater Accra region only (Presidential approval)",
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, "3 day bandwidth" = 3,
                                        "Full sample (ex. protest days)" = 3, "Full sample" = 3)),
       keep = "Post period",
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

maintab1_bono
maintab2_bono
maintab1_ga
maintab2_ga

```

\clearpage 

## Intensity of party attachment

An alternative explanation for our findings is that the strength of partisan attachment confounds exposure to the protest. More specifically, it may be that government partisans interviewed after the protest are more strongly attached to the ruling party than their counterparts interviewed beforehand, and that this divergence in attachment, rather than backlash to the protests, is what drives our overall results. 

As our survey was not designed with the protests in mind, we did not ask precise questions about partisan attachments and so cannot fully rule out this *individual-level* explanation. Instead, we rely on measures of vote choice in the previous general election, which we think provide a proxy for whether or not one is a supporter of the government and likely to identify with the ruling party in some way. We do not use future voting intention in our main analyses due to concerns about post-treatment bias.

In the analyses that follow, however, we provide several additional analyses to instill confidence that our results reflect the impact of the protests rather than differential partisan attachment. 

Fist, we first show that past vote choice does remain strongly predictive of future voting intention in our own survey, before using Afrobarometer data to show that vote intention, in turn, is highly predictive of party identification. While Afrobarometer does not ask questions about past vote choice, this two-step approach provides some evidence that the outcomes remain highly correlated, that party identities in Ghana are relatively stable, and that past vote choice is thus a reasonable proxy for them.

Second, we examine how our main effects vary based on the type of constituency in which a respondent lives, on the assumption that government stronghold constituencies may reflect deeper party networks and higher attachment.^[We are grateful to an anonymous reviewer for suggesting this idea.] While this analysis requires caveats due to the small number of constituencies in our sample (and number of respondents in each one), we find that our effects are *not* driven by government stronghold constituencies but instead by their opposition-held and more competitive counterparts.

### Validating past vote choice as a proxy

To begin, we consider whether our measure of past vote choice continues to predict vote intention, an indicator of present party support.

In Table \@ref(tab:swing-voters), we compare how 2024 vote intention relates to 2020 vote choice. We find strong evidence of retention across voters, with 75% of government voters (132 of 176) of intending to vote for the party again, and 97% of opposition voters (210 of 217) intending to vote for the opposition once more. As expected there is more movement away from the ruling party, which fits the general anti-incumbency mood described in the main text. However the results do provide suggestive evidence that using 2020 vote choice remains a relatively strong proxy of present day party support.

```{r swing-voters, results="asis", fig.pos="hold"}

vote_table <- data %>%
  filter(!vote2020_inc %in% c("Non-voter", "DKs"),
         !is.na(vote_intention)) %>% ## Restrict to those who voted in 2020 and intend to vote in 2024
  group_by(vote2020_inc, vote_intention) %>%
  summarise(count = n(), .groups = 'drop') %>%
  group_by(vote2020_inc) %>%
  mutate(count = count, 
         share = (count / sum(count))*100, 
         share = round(share, 1)) %>%
  ungroup() %>%
  transmute(`2020 Vote Choice` = vote2020_inc, 
            `2024 Intention` = vote_intention, 
            Count = count, 
            `Share of 2020 voters` = share)

kable(vote_table, format = "latex", booktabs = TRUE, 
      caption = "Past vote choice and 2024 intentions") %>%
  kable_styling(latex_options = "hold_position")

```

Next, we rely on data from round 9 of the Afrobarometer to see how vote intention relates to party identification. In this round of the survey, Afrobarometer did not ask questions about vote choice in 2020, so we use vote intention working from the assumption, evidenced above, that vote intention and past vote choice are quite strongly correlated in this setting.

We make use of the standard Afrobarometer question on party identification, which asks respondents first whether they feel close to any party, and if so which party that is. 

In table \@ref(tab:AB-partisanship) we focus on respondents who intend to vote for the government or the opposition. Among government intended voters, 76% (382 of 503) also identify with the ruling party, while among opposition intended voters 58% identify with an opposition party (426 of 731). These results suggest that future vote intention is a strong predictor of party identification, particularly for government supporters. Given the previous results, this suggests that past vote choice is likely a strong indicator of party identification as well.

```{r AB-partisanship, results="asis"}

vote_table <- AB_r9 %>%
  filter(!is.na(vote_intention), !is.na(party_id_govt)) %>%
  group_by(vote_intention, party_id_govt) %>%
  summarise(count = n(), .groups = 'drop') %>%
  group_by(vote_intention) %>%
  mutate(count = count, 
         share = (count / sum(count))*100, 
         share = round(share, 1)) %>%
  ungroup() %>%
  transmute(`2024 Intention` = vote_intention,
            `Party close to` = party_id_govt,
            Count = count, 
            `Share of intended voters` = share)

kable(vote_table, format = "latex", booktabs = TRUE, escape = FALSE,
      caption = "Vote intention and party identification (Afrobarometer R9)") %>%
  kable_styling(latex_options = "hold_position")

```

### Constituency-level heterogeneity

Finally, we use constituency-level electoral data to offer a further proxy of the local strength of party support (and potential partisan attachment). While this approach is not perfect, since individual survey respondents may not be representative of the constituency in which they live, it nonetheless offers further clues about the types of places included in the sample and whether these shape the findings.

Our sample includes 20 electoral constituencies, generally containing 50 respondents each^[As discussed in the main text, one enumeration area sampled an extra respondent so one constituency correspondingly has 51 respondents. Moreover, some constituencies in Accra are geographically small due to higher population density, and so have fewer respondents due to the random walk protocol.]. We link results from the 2020 Presidential election into our dataset, and use this to run several tests of effect heterogeneity. The number of available constituencies is small, and not something we purposively sampled, but we nonetheless see some variation in support for Ghana's two major parties. Figure \@ref(fig:con-spread) plots the distribution if ruling party and opposition vote shares, alongside margin of victory, in each constituency.

```{r con-spread, fig.width=10, fig.height=4, fig.cap="Constituency characteristics"}

data_long <- data %>%
  pivot_longer(cols = c(npp_share, ndc_share), 
               names_to = "party", 
               values_to = "vote_share") %>%
  mutate(party = recode(party, npp_share = "NPP", ndc_share = "NDC"))


# Plot distribution of vote shares
conplot1 <- ggplot(data_long) +
  geom_histogram(aes(x = vote_share, colour = party, fill = party), position="dodge", alpha = 0.3, size = 1) + 
  scale_colour_manual(values = c("NPP" = "darkblue", "NDC" = "darkgreen")) +
  scale_fill_manual(values = c("NPP" = "darkblue", "NDC" = "darkgreen")) +
  labs(x = "Vote Share (%)", y = "Density", 
       title = "Constituency vote share") +
  theme_minimal() +
  theme(legend.title = element_blank(), 
        legend.position = "bottom",
        axis.text.y = element_blank()) 

# Plot distribution of victory margin

data_margin <- data %>%
  mutate(margin_raw = npp_share - ndc_share,
         party = ifelse(margin_raw > 0, "NPP winner", "NDC winner"))

# Plot a single density distribution with the 'party' classification
conplot2 <- ggplot(data_margin) +
  geom_histogram(aes(x = margin_raw, colour = party, fill = party), position = "dodge", alpha = 0.3, size = 1) + 
  scale_colour_manual(values = c("NPP winner" = "darkblue", "NDC winner" = "darkgreen")) +
  scale_fill_manual(values = c("NPP winner" = "darkblue", "NDC winner" = "darkgreen")) +
  labs(x = "NPP vote - NDC vote (%)", y = "Density", title = "Constituency margins of victory") +
  theme_minimal() +
  theme(legend.title = element_blank(),
        legend.position = "bottom",
        axis.text.y = element_blank())

grid.arrange(conplot1, conplot2, nrow=1)

```

We use this data to re-estimate our main models among respondents living in constituencies won by the government party and those living in government strongholds (defined as an NPP victory margin of greater than 20%). Given the limited variation that comes from using just 20 constituencies, we are cautious about reducing sample size to smaller bandwidths as in the initial tests. For instance, under a two day bandwidth the modal constituency in our dataset would have just 10 respondents, raising serious concerns about statistical power. We therefore use the full survey sample for these analyses. 

Figure \@ref(fig:con-measures) plots the spread of our measures of constituency support. Of the 20 seats, 9 were won by the government and 11 were won by the opposition. In government seats the average victory margin was 17.7%, while in opposition seats it was 16.9%. 

```{r con-measures, fig.width=10, fig.height=4, fig.cap="Measures of constituency partisanship"}

con_counts <- data %>% select(con_name, npp_win, margin_raw, govt_stronghold) %>% 
  group_by(con_name) %>% 
  summarise(count = n(), 
            npp_win = npp_win, 
            margin_raw = margin_raw, 
            govt_stronghold = govt_stronghold) %>% 
  distinct(con_name, .keep_all=T)

con_plot3 <- ggplot(con_counts) +
  geom_bar(aes(x = factor(npp_win), fill = factor(npp_win))) + 
  scale_fill_manual(values = c("darkgreen", "darkblue")) +
  labs(x = "Government winner (0/1)", y = "Count", title = "a) Winner") +
  theme_minimal() +
  theme(legend.title = element_blank(),
        legend.position = "bottom")

                 
con_plot4 <- ggplot(con_counts) + 
  geom_bar(aes(x = factor(govt_stronghold), fill = factor(govt_stronghold))) + 
  scale_fill_manual(values = c("darkgreen", "darkblue")) +
  labs(x = "Government stronghold (0/1)", y = "Count", title = "b) Stronghold") +
  theme_minimal() +
  theme(legend.title = element_blank(),
        legend.position = "bottom")

grid.arrange(con_plot3, con_plot4, nrow=1)

```

Using these measures, we then re-run our main UESD specifications to see if effects are driven by government held/stronghold constituencies. Instead, we find the opposite to be the case. Trust in the President is overwhelmingly driven by constituencies that are not held by the government (nor strongholds). For approval, results are consistently positive in non-government seats, while there are positive effects in both strongholds and non-strongholds (though these are not significantly different *from each other*). Taken together, these findings suggest that the strength of local partisanship is not driving the overall effects reported in the main text.

```{r uesd-constituency-het, out=FALSE}

#### NPP wins

julorbi1.1 <- feols(c(trust_pres, performance_pres) ~ i(npp_win, postJulorbi) + npp_win + bono, 
                    data=data) ## Baseline
julorbi1.2 <- feols(c(trust_pres, performance_pres) ~ i(npp_win, postJulorbi) + npp_win +
                      vote2020_inc + age + remittance_quota + 
                      gender + education + urbrur + urbrur_from + bono, data=data) ## Covariates
julorbi1.3 <- feols(c(trust_pres, performance_pres) ~ i(npp_win, postJulorbi) + npp_win + bono, 
                    data=data_eb_fullsample_con, weights=~weights) # Entropy weights


#### NPP stronghold

julorbi2.1 <- feols(c(trust_pres, performance_pres) ~ i(govt_stronghold, postJulorbi) + govt_stronghold + bono, 
                    data=data)
julorbi2.2 <- feols(c(trust_pres, performance_pres) ~ i(govt_stronghold, postJulorbi) + govt_stronghold +
                      vote2020_inc + age + remittance_quota + 
                      gender + education + urbrur + urbrur_from + bono, data=data)
julorbi2.3 <- feols(c(trust_pres, performance_pres) ~ i(govt_stronghold, postJulorbi) + govt_stronghold + bono, 
                    data=data_eb_fullsample_con, weights=~weights)


uesd_results_main <- c(julorbi1.1, julorbi1.2, julorbi1.3, 
                       julorbi2.1, julorbi2.2, julorbi2.3)

## Collate dataset

julorbi_trust_df <- map_df(uesd_results_main, broom::tidy, .id="model") %>%
  filter(term %in% c("npp_win::0:postJulorbi", "npp_win::1:postJulorbi",
                     "govt_stronghold::0:postJulorbi", "govt_stronghold::1:postJulorbi")) %>%
  mutate(conf.low95 = estimate - 1.96*std.error,
         conf.high95 = estimate + 1.96*std.error,
         conf.low90 = estimate - 1.68*std.error,
         conf.high90 = estimate + 1.68*std.error,
         outcome = rep(c("Trust", "Trust", 
                         "Approval", "Approval"), 6),
         group = ifelse(term == "npp_win::0:postJulorbi", "Opposition constituency",
                 ifelse(term == "npp_win::1:postJulorbi", "Government constituency", 
                 ifelse(term == "govt_stronghold::0:postJulorbi", 
                        "Not stronghold", "Government stronghold"))), 
         group2 = ifelse(group %in% c("Opposition constituency", "Government constituency"), 
                         "Constituency winner?", "Constituency stronghold?"),
         spec = rep(c("Baseline", "Baseline", 
                      "Covariates", "Covariates",
                      "Entropy balancing", "Entropy balancing"), 4)) 

```

```{r uesd-constituency-het-tables, results="asis"}

setFixest_dict(c(postJulorbi = "Post period", 
                 trust_pres = "Trust in the President",
                 performance_pres = "Approve President's performance",
                 npp_win = "Government-won constituency", 
                 govt_stronghold = "Government stronghold constituency"))


etable(julorbi1.1[1], julorbi1.2[1], julorbi1.3[1], 
                   julorbi1.1[2], julorbi1.2[2], julorbi1.3[2],
       title = "UESD results (constituency winner)",
       headers = list("^:_:Type" = list("Trust President" = 3, "Approve performance" = 3)),
       keep = c("Post period", "Government-won constituency"),
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "")),
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

etable(julorbi2.1[1], julorbi2.2[1], julorbi2.3[1], 
                         julorbi2.1[2], julorbi2.2[2], julorbi2.3[2],
       title = "UESD results (constituency strongholds)",
       headers = list("^:_:Type" = list("Trust President" = 3, "Approve performance" = 3)),
       keep = c("Post period", "Government stronghold constituency"),
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "")),
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

```


# Robustness II: Excludability {#excludability}

## Alternative outcomes {#altoutcomes}

UESD designs pose a risk of *compound* treatments, where an event encapsulates multiple "treatments" that might influence public opinion. 

Our main findings focus on trust and support for the President, the figurehead of government in Ghana. But in the specifications below, we use a range of alternative (and related) outcomes. For trust, this includes the police, parliament, officials in general, and the electoral commission. For approval, we assess perceptions of how the government has handled the economy, inflation, healthcare, education and corruption. 

We find some evidence that the protest shapes trust in other government and state institutions, especially at higher bandwidths. Results are particularly robust for trust in parliament and the electoral commission. Evidence for government performance is more mixed. At higher bandwidths there is some evidence of improved evaluations of inflation and corruption handling, both of which are intimately related to the demands of the protesters. But effects remain mixed for healthcare, the economy overall, and to a lesser extent education.

```{r results-alt-outcomes, fig.width=8, fig.height=5, fig.cap = "Alternative outcome specifications, presenting the impact of the Julorbi House protests on other dimensions of government trust and approval. All models include region fixed effects, while covariate and entropy specifications account for age, gender, education, and urbancy. Bars represent 95% (thick) and 90% (thin) confidence intervals respectively. Number of observations are lower bounds taken from covariate and entropy models, with more missingness due to additional variables."}

#### 2 day bandwidth (N=336)

data <- data %>% mutate(bono = as.factor(bono))

julorbi1.1 <- feols(c(trust_police, trust_parl, trust_officials, trust_ec, 
                      handle_economy, handle_inflation, handle_health, 
                      handle_education, handle_corruption) ~ postJulorbi2days + bono, data=data) ## Baseline
julorbi1.2 <- feols(c(trust_police, trust_parl, trust_officials, trust_ec, 
                      handle_economy, handle_inflation, handle_health, 
                      handle_education, handle_corruption) ~ postJulorbi2days + 
                      age + gender + vote2020_inc + education + remittance_quota +
                      urbrur + urbrur_from + bono, data=data) ## With wider covariates
julorbi1.3 <- feols(c(trust_police, trust_parl, trust_officials, trust_ec, 
                      handle_economy, handle_inflation, handle_health, 
                      handle_education, handle_corruption) ~ postJulorbi2days + bono, 
                    data=data_eb_2days_alt, weights=~weights) 


#### 3 day bandwidth (N=508)

julorbi2.1 <- feols(c(trust_police, trust_parl, trust_officials, trust_ec, 
                      handle_economy, handle_inflation, handle_health, 
                      handle_education, handle_corruption) ~ postJulorbi3days + bono, data=data) ## Baseline
julorbi2.2 <- feols(c(trust_police, trust_parl, trust_officials, trust_ec, 
                      handle_economy, handle_inflation, handle_health, 
                      handle_education, handle_corruption) ~ postJulorbi3days + 
                      age + gender + vote2020_inc + education + remittance_quota +
                      urbrur + urbrur_from + bono, data=data) ## With wider covariates
julorbi2.3 <- feols(c(trust_police, trust_parl, trust_officials, trust_ec, 
                      handle_economy, handle_inflation, handle_health, 
                      handle_education, handle_corruption) ~ postJulorbi3days + bono, 
                    data=data_eb_3days_alt, weights=~weights) 


#### Full sample excl. protest days (N=627)

julorbi3.1 <- feols(c(trust_police, trust_parl, trust_officials, trust_ec, 
                      handle_economy, handle_inflation, handle_health, 
                      handle_education, handle_corruption) ~ postJulorbi_donut + bono, data=data) ## Baseline
julorbi3.2 <- feols(c(trust_police, trust_parl, trust_officials, trust_ec, 
                      handle_economy, handle_inflation, handle_health, 
                      handle_education, handle_corruption) ~ postJulorbi_donut + 
                      age + gender + vote2020_inc + education + remittance_quota +
                      urbrur + urbrur_from + bono, data=data) ## With wider covariates
julorbi3.3 <- feols(c(trust_police, trust_parl, trust_officials, trust_ec, 
                      handle_economy, handle_inflation, handle_health, 
                      handle_education, handle_corruption) ~ postJulorbi_donut + bono,
                    data=data_eb_fullsample_donut_alt, weights=~weights) 

#### Full sample (N=796)

julorbi4.1 <- feols(c(trust_police, trust_parl, trust_officials, trust_ec, 
                      handle_economy, handle_inflation, handle_health, 
                      handle_education, handle_corruption) ~ postJulorbi + bono, data=data) ## Baseline
julorbi4.2 <- feols(c(trust_police, trust_parl, trust_officials, trust_ec, 
                      handle_economy, handle_inflation, handle_health, 
                      handle_education, handle_corruption) ~ 
                      postJulorbi + age + remittance_quota + vote2020_inc + 
                      age + gender + vote2020_inc + education + remittance_quota +
                      urbrur + urbrur_from + bono, data=data) ## With wider covariates
julorbi4.3 <- feols(c(trust_police, trust_parl, trust_officials, trust_ec, 
                      handle_economy, handle_inflation, handle_health, 
                      handle_education, handle_corruption) ~ postJulorbi + bono, 
                    data=data_eb_fullsample_alt, weights=~weights)

```

```{r results-alt-placebo-outcomes-table, results="asis"}


alt_outcometab1 <- etable(julorbi1.1[1], julorbi1.2[1], julorbi1.3[1], 
                          julorbi2.1[1], julorbi2.2[1], julorbi2.3[1],
                          julorbi3.1[1], julorbi3.2[1], julorbi3.3[1], 
                          julorbi4.1[1], julorbi4.2[1], julorbi4.3[1],
       title = "Alternative outcome: Trust in Police",
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, "3 day bandwidth" = 3, 
                                        "Full sample (ex. protest days)" = 3, 
                                        "Full sample (ex. first protest day)" = 3)),
       keep = "Post period",
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

alt_outcometab2 <- etable(julorbi1.1[2], julorbi1.2[2], julorbi1.3[2], 
                          julorbi2.1[2], julorbi2.2[2], julorbi2.3[2],
                          julorbi3.1[2], julorbi3.2[2], julorbi3.3[2], 
                          julorbi4.1[2], julorbi4.2[2], julorbi4.3[2],
       title = "Alternative outcome: Trust in Parliament",
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, "3 day bandwidth" = 3, 
                                        "Full sample (ex. protest days)" = 3, 
                                        "Full sample (ex. first protest day)" = 3)),
       keep = "Post period",
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

alt_outcometab3 <- etable(julorbi1.1[3], julorbi1.2[3], julorbi1.3[3], 
                          julorbi2.1[3], julorbi2.2[3], julorbi2.3[3],
                          julorbi3.1[3], julorbi3.2[3], julorbi3.3[3], 
                          julorbi4.1[3], julorbi4.2[3], julorbi4.3[3],
       title = "Alternative outcome: Trust in Officials",
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, "3 day bandwidth" = 3, 
                                        "Full sample (ex. protest days)" = 3, 
                                        "Full sample (ex. first protest day)" = 3)),
       keep = "Post period",
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

alt_outcometab4 <- etable(julorbi1.1[4], julorbi1.2[4], julorbi1.3[4], 
                          julorbi2.1[4], julorbi2.2[4], julorbi2.3[4],
                          julorbi3.1[4], julorbi3.2[4], julorbi3.3[4], 
                          julorbi4.1[4], julorbi4.2[4], julorbi4.3[4],
       title = "Alternative outcome: Trust in Electoral Commission",
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, "3 day bandwidth" = 3, 
                                        "Full sample (ex. protest days)" = 3, 
                                        "Full sample (ex. first protest day)" = 3)),
       keep = "Post period",
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

alt_outcometab5 <- etable(julorbi1.1[5], julorbi1.2[5], julorbi1.3[5], 
                          julorbi2.1[5], julorbi2.2[5], julorbi2.3[5],
                          julorbi3.1[5], julorbi3.2[5], julorbi3.3[5], 
                          julorbi4.1[5], julorbi4.2[5], julorbi4.3[5],
       title = "Alternative outcome: Government handling economy",
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, "3 day bandwidth" = 3, 
                                        "Full sample (ex. protest days)" = 3, 
                                        "Full sample (ex. first protest day)" = 3)),
       keep = "Post period",
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

alt_outcometab6 <- etable(julorbi1.1[6], julorbi1.2[6], julorbi1.3[6], 
                          julorbi2.1[6], julorbi2.2[6], julorbi2.3[6],
                          julorbi3.1[6], julorbi3.2[6], julorbi3.3[6], 
                          julorbi4.1[6], julorbi4.2[6], julorbi4.3[6],
       title = "Alternative outcome: Government handling inflation",
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, "3 day bandwidth" = 3, 
                                        "Full sample (ex. protest days)" = 3, 
                                        "Full sample (ex. first protest day)" = 3)),
       keep = "Post period",
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

alt_outcometab7 <- etable(julorbi1.1[7], julorbi1.2[7], julorbi1.3[7], 
                          julorbi2.1[7], julorbi2.2[7], julorbi2.3[7],
                          julorbi3.1[7], julorbi3.2[7], julorbi3.3[7], 
                          julorbi4.1[7], julorbi4.2[7], julorbi4.3[7],
       title = "Alternative outcome: Government handling healthcare",
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, "3 day bandwidth" = 3, 
                                        "Full sample (ex. protest days)" = 3, 
                                        "Full sample (ex. first protest day)" = 3)),
       keep = "Post period",
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

alt_outcometab8 <- etable(julorbi1.1[8], julorbi1.2[8], julorbi1.3[8], 
                          julorbi2.1[8], julorbi2.2[8], julorbi2.3[8],
                          julorbi3.1[8], julorbi3.2[8], julorbi3.3[8], 
                          julorbi4.1[8], julorbi4.2[8], julorbi4.3[8],
       title = "Alternative outcome: Government handling education",
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, "3 day bandwidth" = 3, 
                                        "Full sample (ex. protest days)" = 3, 
                                        "Full sample (ex. first protest day)" = 3)),
       keep = "Post period",
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

alt_outcometab9 <- etable(julorbi1.1[9], julorbi1.2[9], julorbi1.3[9], 
                          julorbi2.1[9], julorbi2.2[9], julorbi2.3[9],
                          julorbi3.1[9], julorbi3.2[9], julorbi3.3[9], 
                          julorbi4.1[9], julorbi4.2[9], julorbi4.3[9],
       title = "Alternative outcome: Government handling corruption",
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, "3 day bandwidth" = 3, 
                                        "Full sample (ex. protest days)" = 3, 
                                        "Full sample (ex. first protest day)" = 3)),
       keep = "Post period",
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)


alt_outcometab1
alt_outcometab2
alt_outcometab3
alt_outcometab4
alt_outcometab5
alt_outcometab6
alt_outcometab7
alt_outcometab8
alt_outcometab9

```

\clearpage

## Placebo outcomes {#placebooutcomes}

We re-run our main specifications using placebo outcomes: *social* rather than political trust. This is not tangibly related to the protest, and so should not see significant movement in the post period. If we do see positive effects on these outcomes, it could suggest that our main results simply reflect a spillover, rather than anything specific about the President and his relation to the protest. 

We measure trust in one's neighbours, in one's relatives, and in "other people you know". Question wordings are near-identical to our main outcomes. All are measured on the *same* 1-4 point scale, making effect sizes comparable.

Across the board, there is no difference in these outcomes between respondents interviewed before and after the protest. Across 48 models only one are statistically significant at the 10% level - neighbours column (9). Given this effect is not replicated at other bandwidths or specifications, we believe it likely arises by chance. 

```{r results-placebo-outcomes, fig.width=8, fig.height=4, fig.cap = "Main UESD specifications, presenting the impact of the Julorbi House protests on Presidential trust and approval. All models include region fixed effects, while covariate and entropy specifications account for age, gender, education, and urbancy. Bars represent 95% (thick) and 90% (thin) confidence intervals respectively. Number of observations are lower bounds taken from covariate and entropy models, with more missingness due to additional variables. Collectively, the results suggest that respondents interviewed after the protest were more trusting and approving of the President."}

#### 2 day bandwidth (N=336)


data <- data %>% mutate(bono = as.factor(bono))

julorbi1.1 <- feols(c(performance_mp, trust_rel, trust_neighbours, trust_others) ~ postJulorbi2days + bono, data=data) ## Baseline
julorbi1.2 <- feols(c(performance_mp, trust_rel, trust_neighbours, trust_others) ~ postJulorbi2days + 
                      age + gender + vote2020_inc + education + remittance_quota +
                      urbrur + urbrur_from + bono, data=data) ## With wider covariates
julorbi1.3 <- feols(c(performance_mp, trust_rel, trust_neighbours, trust_others) ~ postJulorbi2days + bono, data=data_eb_2days_alt, weights=~weights) 


#### 3 day bandwidth (N=508)

julorbi2.1 <- feols(c(performance_mp, trust_rel, trust_neighbours, trust_others) ~ postJulorbi3days + bono, data=data) ## Baseline
julorbi2.2 <- feols(c(performance_mp, trust_rel, trust_neighbours, trust_others) ~ postJulorbi3days + 
                      age + gender + vote2020_inc + education + remittance_quota +
                      urbrur + urbrur_from + bono, data=data) ## With wider covariates
julorbi2.3 <- feols(c(performance_mp, trust_rel, trust_neighbours, trust_others) ~ postJulorbi3days + bono, data=data_eb_3days_alt, weights=~weights) 


#### Full sample excl. protest days (N=627)

julorbi3.1 <- feols(c(performance_mp, trust_rel, trust_neighbours, trust_others) ~ postJulorbi_donut + bono, data=data) ## Baseline
julorbi3.2 <- feols(c(performance_mp, trust_rel, trust_neighbours, trust_others) ~ postJulorbi_donut + 
                      age + gender + vote2020_inc + education + remittance_quota +
                      urbrur + urbrur_from + bono, data=data) ## With wider covariates
julorbi3.3 <- feols(c(performance_mp, trust_rel, trust_neighbours, trust_others) ~ postJulorbi_donut + bono, data=data_eb_fullsample_donut_alt, weights=~weights) 

#### Full sample (N=796)

julorbi4.1 <- feols(c(performance_mp, trust_rel, trust_neighbours, trust_others) ~ postJulorbi + bono, data=data) ## Baseline
julorbi4.2 <- feols(c(performance_mp, trust_rel, trust_neighbours, trust_others) ~ 
                      postJulorbi + age + remittance_quota + vote2020_inc + 
                      age + gender + vote2020_inc + education + remittance_quota +
                      urbrur + urbrur_from + bono, data=data) ## With wider covariates
julorbi4.3 <- feols(c(performance_mp, trust_rel, trust_neighbours, trust_others) ~ postJulorbi + bono, data=data_eb_fullsample_alt, weights=~weights)


```

```{r results-placebo-outcomes-table, results="asis"}

setFixest_dict(c(postJulorbi2days = "Post period", 
                 postJulorbi3days = "Post period",
                 postJulorbi_donut = "Post period",
                 postJulorbi = "Post period", 
                 trust_rel = "Relatives",
                 trust_others = "Other people",
                 trust_neighbours = "Neighbours",
                 performance_mp = "Approve MP's performance"))

alt_outcometab2 <- etable(julorbi1.1[2], julorbi1.2[2], julorbi1.3[2], 
                          julorbi2.1[2], julorbi2.2[2], julorbi2.3[2],
                          julorbi3.1[2], julorbi3.2[2], julorbi3.3[2], 
                          julorbi4.1[2], julorbi4.2[2], julorbi4.3[2],
       title = "Placebo outcomes I (Trust relatives)",
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, "3 day bandwidth" = 3, 
                                        "Full sample (ex. protest days)" = 3, 
                                        "Full sample (ex. first protest day)" = 3)),
       keep = "Post period",
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

alt_outcometab3 <- etable(julorbi1.1[3], julorbi1.2[3], julorbi1.3[3], 
                          julorbi2.1[3], julorbi2.2[3], julorbi2.3[3],
                          julorbi3.1[3], julorbi3.2[3], julorbi3.3[3], 
                          julorbi4.1[3], julorbi4.2[3], julorbi4.3[3],
       title = "Placebo outcomes II (Trust neighbours)",
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, "3 day bandwidth" = 3, 
                                        "Full sample (ex. protest days)" = 3, 
                                        "Full sample (ex. first protest day)" = 3)),
       keep = "Post period",
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

alt_outcometab4 <- etable(julorbi1.1[4], julorbi1.2[4], julorbi1.3[4], 
                          julorbi2.1[4], julorbi2.2[4], julorbi2.3[4],
                          julorbi3.1[4], julorbi3.2[4], julorbi3.3[4], 
                          julorbi4.1[4], julorbi4.2[4], julorbi4.3[4],
       title = "Placebo outcomes III (Trust other people)",
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, "3 day bandwidth" = 3, 
                                        "Full sample (ex. protest days)" = 3, 
                                        "Full sample (ex. first protest day)" = 3)),
       keep = "Post period",
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", "")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

alt_outcometab2
alt_outcometab3
alt_outcometab4





```

\clearpage 

## Placebo population (Afrobarometer) {#abplacebo}

One potential threat to identification is that the Julorbi House protests coincided Ghana's Kwame Nkrumah memorial day - a public holiday celebrating the country's post-independence leader. This threatens our estimates if the national holiday itself increases support for the government. This might occur through rising national pride, or a positive benchmarking of Ghana's current status quo against difficulties around the independence period.

We take data from round 7 of the Afrobarometer survey in Ghana, a nationally representative opinion poll conducted between 9th to 25th September. We use identical questions on trust and approval of the President, alongside an additional measure of national vs ethnic identification; a five point scale which asks respondents to rank the relative importance of their national and ethnic identities. Higher values indicate more weight given to national identity.

Specifications are identical to those in the main text, including region fixed effects at baseline and presenting results with covariates and entropy balancing.  When including covariates, we control for age, gender, education, 2016 vote choice, and whether a respondent lives in an urban area. To ensure maximum comparability with our main effects, we also include a binary measure of financial remittances. Results are presented in the tables below. There are no significant effects on any of the outcomes we study. 


```{r AB-placebo-models-sm, fig.height=4, fig.width=8, fig.cap = "Placebo UESD specifications using round 7 Afrobarometer data (September 2017). Estimates use same specifications as in the main text, but with different data. Bars represent 95% (thick) and 90% (thin) confidence intervals respectively. The results indicate that Nkrumah Memorial day has no signficant impact on national identity, or support for the President."}


## 2 days
ab1.1 <- feols(c(ethnic_salience, trust_pres, performance_pres) ~ postKN2days + i(region), data=r7sub)
ab1.2 <- feols(c(ethnic_salience, trust_pres, performance_pres) ~ postKN2days + age + gender + remittances_bin + 
        vote2016_inc + education + urbrur +  i(region), data=r7sub)
ab1.3 <- feols(c(ethnic_salience, trust_pres, performance_pres) ~ postKN2days  + i(region), data=data_eb_ab_2days, weights = ~weights)

## 3 days
ab2.1 <- feols(c(ethnic_salience, trust_pres, performance_pres) ~ postKN3days  + i(region), data=r7sub)
ab2.2 <- feols(c(ethnic_salience, trust_pres, performance_pres) ~ postKN3days  + age + gender + remittances_bin + 
        vote2016_inc + education + urbrur +  i(region), data=r7sub)
ab2.3 <- feols(c(ethnic_salience, trust_pres, performance_pres) ~ postKN3days  + i(region), data=data_eb_ab_3days, weights = ~weights)

## 4 days
ab3.1 <- feols(c(ethnic_salience, trust_pres, performance_pres) ~ postKN4days  + i(region), data=r7sub)
ab3.2 <- feols(c(ethnic_salience, trust_pres, performance_pres) ~ postKN4days  + age + gender + remittances_bin + 
        vote2016_inc + education + urbrur + i(region), data=r7sub)
ab3.3 <- feols(c(ethnic_salience, trust_pres, performance_pres) ~ postKN4days  + i(region), data=data_eb_ab_4days, weights = ~weights)

```

```{r AB-placebo-tabs-print, results="asis"}

setFixest_dict(c(postKN2days = "Post period", 
                 postKN3days = "Post period",
                 postKN4days = "Post period",
                 postKN = "Post period", 
                 trust_pres = "Trust in the President",
                 performance_pres = "Approve President's performance", 
                 ethnic_salience = "National vs ethnic ID",
                 age = "Age", 
                 gender = "Male", 
                 remittances_bin = "Remittances", 
                 vote2016_inc = "2016 vote choice", 
                 education = "Education", 
                 urbrur = "Urban rural"))


ABtab1 <- etable(ab1.1[1], ab1.2[1], ab1.3[1],
                 ab2.1[1], ab2.2[1], ab2.3[1],
                 ab3.1[1], ab3.2[1], ab3.3[1],
       title = "Afrobarometer results (National vs ethnic identification)",
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, "3 day bandwidth" = 3, "4 day bandwidth" = 3)),
       keep = "Post period",
       drop = "region",
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", ""),
                       "_^Region FEs"=c("Yes", "Yes", "Yes",
                                        "Yes", "Yes", "Yes",
                                        "Yes", "Yes", "Yes")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)

ABtab2 <- etable(ab1.1[2], ab1.2[2], ab1.3[2],
                 ab2.1[2], ab2.2[2], ab2.3[2],
                 ab3.1[2], ab3.2[2], ab3.3[2],
       title = "Afrobarometer results (Trust in the President)",
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, "3 day bandwidth" = 3, "4 day bandwidth" = 3)),
       keep = "Post period",
       drop = "region",
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", ""),
                       "_^Region FEs"=c("Yes", "Yes", "Yes",
                                        "Yes", "Yes", "Yes",
                                        "Yes", "Yes", "Yes")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)


ABtab3 <- etable(ab1.1[3], ab1.2[3], ab1.3[3],
                 ab2.1[3], ab2.2[3], ab2.3[3],
                 ab3.1[3], ab3.2[3], ab3.3[3],
       title = "Afrobarometer results (Presidential approval)",
       headers = list("^:_:Type" = list("2 day bandwidth" = 3, "3 day bandwidth" = 3, "4 day bandwidth" = 3)),
       keep = "Post period",
       drop = "region",
       digits = 3,
       digits.stats = 3,
       fontsize = "tiny",
       extralines=list("_^Weights"=c("", "", "Yes",
                                     "", "", "Yes",
                                     "", "", "Yes"),
                       "_^Controls"=c("", "Yes", "",
                                      "", "Yes", "",
                                      "", "Yes", ""),
                       "_^Region FEs"=c("Yes", "Yes", "Yes",
                                        "Yes", "Yes", "Yes",
                                        "Yes", "Yes", "Yes")),
       convergence = FALSE, 
       se.row=FALSE,
       tex=T)


ABtab1
ABtab2
ABtab3



```

